*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI addObject:]: unrecognized selector sent to instance 0x4b17be0'
错误:NSArray 不能使用 addObject:方法。可能是在程序运行的过程中,NSMutableArray转为了NSArray。
解决方案:核查数组,看看是否在NSArray 之后使用了addObject:方法 。
延伸:copy属性关键字的使用
iOS 开发中 copy 关键字的使用
在iOS开发中,一般copy关键字用在NSString、NSArray、NSDictionary等属性字段的修饰符。
为什么上述属性需要使用copy修饰呢?原因是上述属性都有可变的子类,如 NSString->NSMutableString、NSArray->NSMutableArray、NSDictionary->NSMutableDictionary;根据面相对象的多态特性,NSString类型的变量可以指向NSMutableString类型的变量。声明对象的属性一般都是希望明确知道对象的值,但是如果对子类是可变类型的属性使用strong修饰的话,可能会在对象不知情的情况下修改对象属性的值,这肯定是对象不愿意看到的,示例代码如下:
图一所示为创建的测试模型,有三个属性,用strong修饰,下图是对模型属性赋值,进行打印的结果
从上边打印结果可以看出,对象的属性在不知情的情况下,内容已经被改变了,这会造成在访问这个对象的时候,属性值不正确的问题,严重的会导致程序崩溃(取数组的下标越界)。
如果使用copy修饰就不会有问题,示例代码如下:
只是改变了属性的修饰符,把strong改为了copy,打印结果如下:
从上图可以看到,改为copy后,对象的属性值,没有因为可变对象值的改变而改变,这正是对象想要的。
所以,属性的修饰符使用copy还是strong,取决于修饰的类型是否有可变类型的子类。