copy与mutableCopy

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。

你可能感兴趣的:(copy与mutableCopy)