OC中使用copy和strong修饰数组的区别

NSArray与NSMutableArray应该使用copy还是strong?

1. 首先我们用strong修饰试一下:

// strong
@property (nonatomic, strong) NSArray *array;
@property (nonatomic, strong) NSMutableArray *mutArray;

// 全部用strong修饰
- (void)testStrong
{
    self.mutArray = [NSMutableArray arrayWithObject:@"000"];
    self.array = @[@"111"];
    NSLog(@"mutArray1->%@,array1->%@",self.mutArray,self.array);
    NSLog(@"%p-%p",self.array, self.mutArray);

    self.array = self.mutArray;
    [self.mutArray addObject:@"666"];
    NSLog(@"mutArray2->%@,array2->%@",self.mutArray,self.array);
    NSLog(@"%p-%p",self.array, self.mutArray);
}
  • 打印地址如下:
    image.png
  • 打印结果:
    mutArray1->(
    000
    ), array1->(
    111
    )
    mutArray2->(
    000,
    666
    ),array2->(
    000,
    666
    )

可以看出mutArrayarray都被修改了。array创建的时候虽然是不可变数组,但是当用可变数组(mutArray)赋值给不可变数组(array)的时候,出现了不是预料的结果。也就是说array也变成了可变数组。
self.array = self.mutArray; -> 这行代码将可变数组的指针赋值给了不可变数组指针,此时mutArrayarray都是指向了同一个内存地址,即mutArray的内存地址,因此后面修改mutArray的数据也会导致array的数据修改,因为是同一块内存地址。

2. 用copy修饰array

@property (nonatomic, copy) NSArray *array;
@property (nonatomic, strong) NSMutableArray *mutArray;

// copy修饰array
- (void)testStrong
{
    self.mutArray = [NSMutableArray arrayWithObject:@"000"];
    self.array = @[@"111"];
    NSLog(@"mutArray1->%@,array1->%@",self.mutArray,self.array);
    NSLog(@"%p-%p",self.array, self.mutArray);
    
    self.array = self.mutArray;
    [self.mutArray addObject:@"666"];
    NSLog(@"mutArray2->%@,array2->%@",self.mutArray,self.array);
    NSLog(@"%p-%p",self.array, self.mutArray);
}
  • 打印地址如下:
    image.png
  • 打印结果:
    mutArray1->(
    000
    ),array1->(
    111
    )
    mutArray2->(
    000,
    666
    ),array2->(
    000
    )

可以看出:用copy修饰的array,通过self.array = self.mutArray;赋值后,mutArray添加了对象,但是array并没有相应的添加。说明array对mutArray之前的值进行了复制。

3. 用copy修饰mutArray

@property (nonatomic, copy) NSMutableArray *mutArray;

// copy修饰mutArray
- (void)testCopy
{
    self.mutArray = [NSMutableArray arrayWithObject:@"000"];
    
    [self.mutArray addObject:@"666"];   // 在这行代码会崩溃
}
  • 打印结果:
    Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSSingleObjectArrayI addObject:]: unrecognized selector sent to instance 0x600001ae04f0'

原因:self.mutArray = [NSMutableArray arrayWithObject:@"000"];这行代码将得到一个不可变的数组(copy属性导致的)。可以通过断点打印self.mutArray的数据类型就会发现实际上是NSArray类型的。而NSArray类型是没有addObject:方法,所以会导致奔溃。

通过上面的测试发现:

1⃣️ NSArray应该用copy来修饰,能确保数据的正确性。
如通过self.array = self.mutArray;方式赋值的时候会出现问题
2⃣️ NSMutableArray使用strong来修饰,而不能用copy修饰。
[self.mutArray addObject:@"666"];对mutArray进行修改的时候会奔溃

@property (nonatomic, copy) NSArray *array;
@property (nonatomic, strong) NSMutableArray *mutArray;

你可能感兴趣的:(OC中使用copy和strong修饰数组的区别)