文章

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 进行授权