【那些年我们遇到的坑】可变容器类属性copy问题

你肯定看到、写过或遇到过这种代码

@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属性,防止错误的发生!

你可能感兴趣的:(【那些年我们遇到的坑】可变容器类属性copy问题)