你肯定看到、写过或遇到过这种代码
@property (nonatomic, copy) NSMutableArray *arrayCopy
写一下问题代码:
@interface MyObject : NSObject
@property(nonatomic, copy) NSMutableArray *arrayCopy;
@property(nonatomic, strong) NSMutableArray *arrayStrong;
@end
@implementation MyObject
- (void)practice {
// ...Test...
}
@end
网络上很多都会说,如果你写了copy属性的NSMutableArray,当你进行增删改的时候,就会报错:
[__NSArray0 addObject:]: unrecognized selector sent to instance 0x100202290
这个错误,是因为copy修饰的属性,在调用增删改的时候,会进行copy操作,而copy操作得到的是一个不可变变量,即NSArray。
NSMutableArray *a = [NSMutableArray new];
NSLog(@"%@->%@", [a class], [[a copy] class]);
// __NSArrayM->__NSArray0
也肯定有人说,MD,老子怎么用,都没报错啊!!!
没错,你不是没报错,你只是对于成员变量的使用没有选择正确的方式,所以,你才会非常巧的没有报错!
看接下来两个实现:
- (void)practice {
self.arrayCopy = [[NSMutableArray alloc] init];
[self.arrayCopy addObject:@"copy1"];
}
- (void)practice {
_arrayCopy = [[NSMutableArray alloc] init];
[self.arrayCopy addObject:@"copy1"];
}
发现不同了吗?没错,第一个是会报错的代码,而第二个是不会报错的。为什么呢?因为第二个没有使用self.的调用,也就是没有调用arrayCopy成员变量的set方法,而只是单纯的赋值给了它,这种情况下,是不会调用copy方法的,因此,你并没有触发copy的报错!
因此,建议进行变量调用赋值时,尽可能使用self.的形式,而且对于可变容器类,一定不要使用copy属性,防止错误的发生!