探究OC中使用copy和strong修饰数组的后果
使用copy修饰数组
a. 不可变指向不可变
//Person.h
@interface Person : NSObject
@property(nonatomic, copy) NSArray * testArray;
@end
// 测试代码
NSArray *arr = @[@1,@2,@3];
Person *p = [[Person alloc]init];
p.testArray = arr;
NSLog(@"arr-->%p", arr);
NSLog(@"testArray-->%p", p.testArray);
// 打印结果
2021-07-05 08:16:13.857483+0800 oc[15206:2039859] arr-->0x1006682e0
2021-07-05 08:16:13.857858+0800 oc[15206:2039859] testArray-->0x1006682e0
// 结论
用copy修饰不可变数组, 将不可变数组赋值给它的时候, 并没有发生拷贝操作
b. 不可变指向可变
//Person.h
@interface Person : NSObject
@property(nonatomic, copy) NSArray * testArray;
@end
// 测试代码
NSMutableArray *arr = [[NSMutableArray alloc]initWithArray:@[@1,@2,@3]];
Person *p = [[Person alloc]init];
p.testArray = arr;
NSLog(@"arr-->%p", arr);
NSLog(@"testArray-->%p", p.testArray);
// 打印结果
2021-07-05 08:18:25.676517+0800 oc[15219:2041472] arr-->0x10051f530
2021-07-05 08:18:25.676892+0800 oc[15219:2041472] testArray-->0x10051f480
// 结论
用copy修饰不可变数组, 将可变数组赋值给它的时候, 发生了拷贝操作, 地址已经变化
c. 可变指向不可变
//Person.h
@interface Person : NSObject
@property(nonatomic, copy) NSMutableArray * testArray;
@end
// 测试代码
NSArray *arr = @[@1,@2,@3];
Person *p = [[Person alloc]init];
p.testArray = arr;
NSLog(@"arr-->%p", arr);
NSLog(@"testArray-->%p", p.testArray);
[p.testArray addObject:@4];
// 编译器有警告, 子类不可指向父类,但是可以运行
// 打印结果
2021-07-05 08:23:57.149590+0800 oc[15271:2045220] arr-->0x10509d930
2021-07-05 08:23:57.150044+0800 oc[15271:2045220] testArray-->0x10509d930
2021-07-05 08:23:57.150265+0800 oc[15271:2045220] -[__NSArrayI addObject:]: unrecognized selector sent to instance 0x10509d930
// 结论
用copy修饰可变数组, 将不可变数组赋值给它的时候, 没有发生拷贝操作, 并且person的可变数组真实指向的是一个不可变数组, 添加元素会崩溃.
d. 可变指向可变
//Person.h
@interface Person : NSObject
@property(nonatomic, copy) NSMutableArray * testArray;
@end
// 测试代码
NSMutableArray *arr = [[NSMutableArray alloc]initWithArray:@[@1,@2,@3]];
Person *p = [[Person alloc]init];
p.testArray = arr;
NSLog(@"arr-->%p", arr);
NSLog(@"testArray-->%p", p.testArray);
[p.testArray addObject:@4];
// 打印结果
2021-07-05 08:26:55.684435+0800 oc[15300:2048005] arr-->0x10061d170
2021-07-05 08:26:55.684825+0800 oc[15300:2048005] testArray-->0x10061d0c0
2021-07-05 08:26:55.685061+0800 oc[15300:2048005] -[__NSArrayI addObject:]: unrecognized selector sent to instance 0x10061d0c0
// 结论
用copy修饰可变数组, 将可变数组赋值给它的时候, 地址变化发生了拷贝操作, 并且person的可变数组真实指向的是一个拷贝出来的不可变数组, 添加元素会崩溃.
使用strong修饰数组
a. 不可变指向不可变
//Person.h
@interface Person : NSObject
@property(nonatomic, strong) NSArray * testArray;
@end
// 测试代码
NSArray *arr = @[@1,@2,@3];
Person *p = [[Person alloc]init];
p.testArray = arr;
NSLog(@"arr-->%p", arr);
NSLog(@"testArray-->%p", p.testArray);
// 打印结果
2021-07-05 08:32:29.411032+0800 oc[15342:2051603] arr-->0x10524b4e0
2021-07-05 08:32:29.411437+0800 oc[15342:2051603] testArray-->0x10524b4e0
// 结论
用strong修饰不可变数组, 将不可变数组赋值给它的时候, 并没有发生拷贝操作, 地址为发生变化, 只是单纯的强引用
b. 不可变指向可变
//Person.h
@interface Person : NSObject
@property(nonatomic, strong) NSArray * testArray;
@end
// 测试代码
NSMutableArray *arr = [[NSMutableArray alloc]initWithArray:@[@1,@2,@3]];
Person *p = [[Person alloc]init];
p.testArray = arr;
NSLog(@"arr-->%p", arr);
NSLog(@"testArray-->%p", p.testArray);
// 打印结果
2021-07-05 08:34:00.060391+0800 oc[15357:2052857] arr-->0x100746350
2021-07-05 08:34:00.060774+0800 oc[15357:2052857] testArray-->0x100746350
// 结论
用strong修饰不可变数组, 将可变数组赋值给它的时候, 并没有发生拷贝操作, 地址未发生变化
c. 可变指向不可变
//Person.h
@interface Person : NSObject
@property(nonatomic, strong) NSMutableArray * testArray;
@end
// 测试代码
NSArray *arr = @[@1,@2,@3];
Person *p = [[Person alloc]init];
p.testArray = arr;
NSLog(@"arr-->%p", arr);
NSLog(@"testArray-->%p", p.testArray);
[p.testArray addObject:@4];
// 编译器有警告, 子类不可指向父类,但是可以运行
// 打印结果
2021-07-05 08:36:01.415302+0800 oc[15380:2054415] arr-->0x105965f00
2021-07-05 08:36:01.415690+0800 oc[15380:2054415] testArray-->0x105965f00
2021-07-05 08:36:01.415902+0800 oc[15380:2054415] -[__NSArrayI addObject:]: unrecognized selector sent to instance 0x105965f00
// 结论
用strong修饰可变数组, 将不可变数组赋值给它的时候, 没有发生拷贝操作, 并且person的可变数组真实指向的是一个不可变数组, 添加元素会崩溃.
d. 可变指向可变
//Person.h
@interface Person : NSObject
@property(nonatomic, copy) NSMutableArray * testArray;
@end
// 测试代码
NSMutableArray *arr = [[NSMutableArray alloc]initWithArray:@[@1,@2,@3]];
Person *p = [[Person alloc]init];
p.testArray = arr;
NSLog(@"arr-->%p", arr);
NSLog(@"testArray-->%p", p.testArray);
[p.testArray addObject:@4];
// 打印结果
2021-07-05 08:37:26.664070+0800 oc[15398:2055650] arr-->0x10589c6a0
2021-07-05 08:37:26.664413+0800 oc[15398:2055650] testArray-->0x10589c6a0
// 结论
用strong修饰可变数组, 将可变数组赋值给它的时候, 地址未变化, 并且person的可变数组真实指向可变数组, 添加元素会正常.
总结
修饰词 | 被修饰数组 | 被指向数组 | 结论 |
---|---|---|---|
copy | 不可变 | 不可变 | 地址未变, 未发生拷贝操作 |
copy | 不可变 | 可变 | 地址变化, 发生拷贝操作 |
copy | 可变 | 不可变 | 本身子类指向父类是不允许的, 这种基本可忽略, 没有发生拷贝, 最终指向的是一个并不可变数组 |
copy | 可变 | 可变 | 地址变化, 发生拷贝操作, 添加元素会崩溃, 因为拷贝出的是一个不可变数组 |
strong | 不可变 | 不可变 | 地址没有变化, 不会拷贝, 单纯引用而已 |
strong | 不可变 | 可变 | 地址未变, 不会拷贝, 单纯引用 |
strong | 可变 | 不可变 | 子类指向父类编译器警告, 不会拷贝, 单纯引用一个不可变数组, 添加元素崩溃 |
strong | 可变 | 可变 | 地址未变化, 不会拷贝, 添加正常 |