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);
}
- 打印地址如下:
- 打印结果:
mutArray1->(
000
), array1->(
111
)
mutArray2->(
000,
666
),array2->(
000,
666
)
可以看出: mutArray和array都被修改了。array创建的时候虽然是不可变数组,但是当用可变数组(mutArray)赋值给不可变数组(array)的时候,出现了不是预料的结果。也就是说array也变成了可变数组。
注:self.array = self.mutArray; -> 这行代码将可变数组的指针赋值给了不可变数组指针,此时mutArray和array都是指向了同一个内存地址,即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);
}
- 打印地址如下:
- 打印结果:
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;