iOS学习程序员iOS Developer

iOS开发之:copy和mutableCopy

2017-03-28  本文已影响106人  life白玉兰

前几天面试被问到copy和mutableCopy的知识,一开始答得是对的,但是被面试官饶了几圈就有点懵了,因为对方问的问题虽然表述不一样,但是后面问的问题在我感觉已经和前面的重复了两三次了,所以回答的时候有些犹豫,有些怀疑是不是自己没听明白对方的意思,然后就没跟上对方的节奏懵了😂

大篇幅的理论我没有时间去写,所以就简单写了点代码来测试下copy和mutableCopy的各种情况,如果有不对的或者不全的地方请大神指正!🙏

为了简单我只以NSArray和NSMutableArray为例来说明

第一种:copy方法,NSArray赋值

NSArray *array = [[NSArray alloc]init];

NSMutableArray *mutableArray = [[NSMutableArray alloc]init];

NSArray *baseArray = [NSArray arrayWithObjects:@"aaaaa", @"bbbb", @"ccccc", @"Block", nil];

array = [baseArray copy];

mutableArray = [baseArray copy];

NSLog(@"origin array: %p, %p, %@",baseArray, &baseArray, baseArray);

NSLog(@"copy array: %p, %p, %@",array, &array, array);

NSLog(@"copy mutableArray: %p, %p, %@", mutableArray, &mutableArray, mutableArray);

[mutableArray removeObjectAtIndex:0];

运行时我打了断点然后po了一下baseArray、array和mutableArray的class,如下是打印出的结果:

(lldb) po baseArray.class

__NSArrayI

(lldb) po array.class

__NSArrayI

(lldb) po mutableArray.class

__NSArrayI

可以看到,三者class类型都是__NSArrayI,mutableArray可变数组在经过copy方法后变成了不可变数组

 origin array: 0x600000057df0, 0x7fff51719bd0, (

aaaaa,

bbbb,

ccccc,

Block

)

 copy array: 0x600000057df0, 0x7fff51719be0, (

aaaaa,

bbbb,

ccccc,

Block

)

 copy mutableArray: 0x600000057df0, 0x7fff51719bd8, (

aaaaa,

bbbb,

ccccc,

Block

)

可以看到,三者指向的地址是一样的

-[__NSArrayI removeObjectAtIndex:]: unrecognized selector sent to instance 0x60000005de20

也证明了mutableArray确实变成了不可变数组

*小结:用copy方法时,如果被copy对象为不可变类型,此时为浅拷贝,被赋值对象无论是否可变都将变为不可变对象

第二种:copy方法,NSMutableArray赋值

在.m文件中将

NSArray *baseArray = [NSArray arrayWithObjects:@"aaaaa", @"bbbb", @"ccccc", @"Block", nil];

改为:

NSMutableArray *baseArray = [NSMutableArray arrayWithObjects:@"aaaaa", @"bbbb", @"ccccc", @"Block", nil];

其他保持不变,我们继续运行,同样po一下:

(lldb) po baseArray.class

__NSArrayM

(lldb) po array.class

__NSArrayI

(lldb) po mutableArray.class

__NSArrayI

在这里可以看出,baseArray没有变(当然不会变🙄)依然是可变数组,array和mutableArray则是不可变数组

 origin array: 0x608000047c80, 0x7fff52b7ebd8, (

aaaaa,

bbbb,

ccccc,

Block

)

copy array: 0x600000055f60, 0x7f80c141fe68, (

aaaaa,

bbbb,

ccccc,

Block

)

copy mutableArray: 0x60800004d6e0, 0x7f80c141fe70, (

aaaaa,

bbbb,

ccccc,

Block

)

这里可以看出array和mutableArray在copy方法时生成了新的对象

 -[__NSArrayI removeObjectAtIndex:]: unrecognized selector sent to instance 0x60800004d6e0

最后mutableArray执行删除操作发生奔溃

*小结:用copy方法时,如果被copy对象为可变类型,此时为深拷贝,被赋值对象无论是否可变都将变为不可变对象

第三种:mutableCopy方法,NSArray赋值

NSArray *array = [[NSArray alloc]init];

NSMutableArray *mutableArray = [[NSMutableArray alloc]init];

NSArray *baseArray = [NSArray arrayWithObjects:@"aaaaa", @"bbbb", @"ccccc", @"Block", nil];

array = [baseArray mutableCopy];

mutableArray = [baseArray mutableCopy];

NSLog(@"origin array: %p, %p, %@",baseArray, &baseArray, baseArray);

NSLog(@"copy array: %p, %p, %@",array, &array, array);

NSLog(@"copy mutableArray: %p, %p, %@", mutableArray, &mutableArray, mutableArray);

[mutableArray removeObjectAtIndex:0];

我们继续运行,同样po一下:

(lldb) po baseArray.class

__NSArrayI

(lldb) po array.class

__NSArrayM

(lldb) po mutableArray.class

__NSArrayM

可以看到,array和mutableArray的class类型都是__NSArrayM,array不变数组在经过mutableCopy方法后变成了可变数组

 origin array: 0x608000059cb0, 0x7fff5b530bd0, (

aaaaa,

bbbb,

ccccc,

Block

)

 copy array: 0x60000005e090, 0x7fff5b530be0, (

aaaaa,

bbbb,

ccccc,

Block

)

copy mutableArray: 0x6000000576a0, 0x7fff5b530bd8, (

aaaaa,

bbbb,

ccccc,

Block

)

这里可以看出array和mutableArray在mutableCopy方法时生成了新的对象,[mutableArray removeObjectAtIndex:0];不会再引起奔溃。

*小结:用mutableCopy方法时,如果被mutableCopy对象为不可变类型,此时也为深拷贝,被赋值对象无论是否可变都将变为可变对象

第四种:mutableCopy方法,NSMutableArray赋值

NSArray *array = [[NSArray alloc]init];

NSMutableArray *mutableArray = [[NSMutableArray alloc]init];

NSMutableArray *baseArray = [NSMutableArray arrayWithObjects:@"aaaaa", @"bbbb", @"ccccc", @"Block", nil];

array = [baseArray mutableCopy];

mutableArray = [baseArray mutableCopy];

NSLog(@"origin array: %p, %p, %@",baseArray, &baseArray, baseArray);

NSLog(@"copy array: %p, %p, %@",array, &array, array);

NSLog(@"copy mutableArray: %p, %p, %@", mutableArray, &mutableArray, mutableArray);

[mutableArray removeObjectAtIndex:0];

我们继续运行,同样po一下:

(lldb) po baseArray.class

__NSArrayM

(lldb) po array.class

__NSArrayM

(lldb) po mutableArray.class

__NSArrayM

可以看到,三者class类型都是__NSArrayM,array不变数组在经过mutableCopy方法后变成了可变数组

origin array: 0x600000051490, 0x7fff54acdbd0, (

aaaaa,

bbbb,

ccccc,

Block

)

copy array: 0x600000056c80, 0x7fff54acdbe0, (

aaaaa,

bbbb,

ccccc,

Block

)

copy mutableArray: 0x60800005bf00, 0x7fff54acdbd8, (

aaaaa,

bbbb,

ccccc,

Block

)

这里可以看出array和mutableArray在mutableCopy方法时生成了新的对象,[mutableArray removeObjectAtIndex:0];不会再引起奔溃。

*小结:用mutableCopy方法时,如果被mutableCopy对象为可变类型,此时也为深拷贝,被赋值对象无论是否可变都将变为可变对象

总结:

1.copy在被拷贝对象为不可变类型时为浅拷贝,在被拷贝对象为可变类型时为深拷贝;

2.无论copy的被拷贝对象是否可变,其返回值一定为不可变类型;

3.mutableCopy为深拷贝,无论被拷贝对象是否可变,其返回值一定为可变类型;

上一篇下一篇

猜你喜欢

热点阅读