Property中好玩的修饰符-copy和strong

1.引

看一段代码

@interface ViewController ()
@property (nonatomic, copy) NSMutableArray *array;
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];

    self.array = [NSMutableArray array];
    [self.array addObject:@"A"];
@end

结果是系统崩溃,后台打印如下错误信息

2018-04-03 15:02:11.238078+0800 iOS[55183:3743941] -[__NSArray0 addObject:]: unrecognized selector sent to instance 0x6040000065a0
2018-04-03 15:02:11.242691+0800 iOS[55183:3743941] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArray0 addObject:]: unrecognized selector sent to instance 0x6040000065a0'

这个时候如果将array的初始化方法换成

_array = [NSMutableArray array];

运行正常!

2.原因

不讨论copy和strong的区别,百度可以找到一堆,这里只讨论为什么_array不会崩溃!那貌似标题就得改了。。。

Java里有一个名词叫Bean,对属性生成setter和getter方法之后,这个变量就是一个bean;
回到OC,系统会自动对@property变量生成setter和getter方法,也就是一个bean,它们其实都是在这个变量的基础上封了一层,我们用到懒加载的时候是要对自己的变量自己写读和写的方法

//getter:
- (NSMutableArray *)array {
    NSLog("%@", _array);
    return _array;
}
//setter:
- (void)setArray:(NSMutableArray *)newValue {
    _array = newValue;
}

用到的就是_array.所以直接使用_array是绕过了getter方法和setter方法,那么_array是直接操作了实例变量;
再来,系统申明一个变量的时候默认是__strong也就是说_array是一个被strong修饰的变量,并不是copy修饰的。

id objc = [NSObject new];
//完整的代码是这个
id __strong objc = [NSObject new];

理解了上面的原因之后,总结一下,self.array是使用了系统的setter和getter,所以array初始化的时候,将[NSMutableArray array]这个对象copy了一下,变成了[array copy]传给了_array,NSArray是NSMutableArray的父类,没有addObject的方法,所以崩溃了~

3. 解决

最好的方法是,将修饰符

@property (nonatomic, strong) NSMutableArray *array;

你可能感兴趣的:(Property中好玩的修饰符-copy和strong)