copy 关键字
第一个问题:打印结果是什么?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@interface ViewController ()
@property(nonatomic, copy)NSMutableArray *array;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.array = [NSMutableArray arrayWithArray:@[@"a", @"b"]];
[self.array addObject:@"c"];
NSLog(@"%@", self.array);
}
@end
答案:会崩溃哦
Thread 1: "-[__NSArray0 addObject:]: unrecognized selector sent to instance原因:如果赋值过来的是可变对象,copy 后会变成不可变对象。
两个规律:
1、不可变对象的 copy 是浅拷贝,其他情况都是深拷贝。
2、copy 返回的都是不可变对象。
为什么不可变对象的 copy 是浅拷贝?
- 性能优化:
避免不必要的复制: 对于不可变对象,创建新副本不会提供额外的好处,因为内容不会发生变化。因此,优化的 copy 实现通常会直接返回原始对象的引用。这避免了不必要的内存分配和对象创建,从而提高了性能。 - 内存管理:
共享实例: 不可变对象的内存管理更高效。多个变量可以安全地共享同一个对象实例,而不会引发数据一致性问题。这也是为什么 copy 操作不需要创建新实例的原因。
第二个问题:使用 copyItems ,arrayB 的元素指针地址 和 arrayB 相同吗
1
2
3
4
NSArray *arrayA = @[@"a"];
NSArray *arrayB = [[NSArray alloc] initWithArray:arrayA copyItems:YES];
NSLog(@"=== arrayA: %p, arrayB: %p", arrayA, arrayB);
NSLog(@"=== arrayA element: %p, arrayB element: %p", arrayA[0], arrayB[0]);
- 答案:新数组的元素指针地址相同,并没有完全深拷贝。
- 原因:其实还是优化成浅拷贝了。
思考:
- 对于不可变对象而言,
浅拷贝和strong是不是没啥区别? - NSString 对象 一定要用 copy 修饰么?
本文由作者按照 CC BY 4.0 进行授权