2018.4.25
先来看代码:
NSMutableArray *listA = [NSMutableArray arrayWithObjects:@"a", @"b", @"c", @"d",nil];
NSMutableArray *listB = [listA copy];
NSLog(@"listB:%@",listB);
for (NSInteger i = listA.count - 1; i >= 0; i--) {
[listB addObject:listA[i]];
}
NSLog(@"listB:%@",listB);
以下代码执行的结果是什么?打印的结果是什么?有问题的话应该应该如何修改?
准备离职了,这是老大为了招新人出的面试题,刚看到时就知道这个题能难住自己了。因为看到copy这个词,脑里的第一印象是block和NSString,copy都是作为他们的修饰词,一个对象来调用copy方法还真的没细想过,也没用过。
考察的知识点:
copy:创建的是不可变对象,NSString、NSArray等
mutableCopy:创建的是可变对象,NSMutableString、NSMutableArray等
所以,上面代码执行时是会Crash的,listB本质上是个不可变的NSArray,没有对应的addObject方法。
NSMutableArray *listB = [listA copy];
NSMutableArray *listC = [listA mutableCopy];
通过断点可以看到不可变和可变对应的分别是__NSArrayI和__NSArrayM
Printing description of listB:
<__NSArrayI 0x1c02511c0>(
a,
b,
c,
d
)
Printing description of listC:
<__NSArrayM 0x1c02529c0>(
a,
b,
c,
d
)
所以修改代码时,就需要用mutableCopy来替代copy。
查阅资料(参考)也可以发现copy与mutableCopy的原则:
修改新(旧)对象,不影响旧(新)对象。
源对象:可变、不可变
调用方法:copy、mutableCopy
就会有四种组合:
- 可变(源) x copy = 不可变(新)
- 可变(源) x mutableCopy = 可变(新)
- 不可变(源) x copy = 不可变(新)
- 不可变(源) x mutableCopy = 可变(新)
另一个隐形的原则就是:
节省内存
第三种组合,copy前后两个对象都不可以修改,永远也不会影响到另一个对象,系统为了节省内存,采取了指针copy,而不是内存copy。
网友评论