探究OC中使用copy和strong修饰数组的后果

探究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可变可变地址未变化, 不会拷贝, 添加正常
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值