iOS开发 copy修饰属性
既然上篇提到了copy相关的知识点,那么趁热打铁介绍一下为什么字符串的属性,要用copy修饰。
介绍之前,先回忆一下属性修饰符都有哪些:
MRC:
assign:基本数据类型(当出现循环引用时,也要用assign)
retain:除Block和NSString外的其他对象
copy:一般用于NSString和Block
ARC:
strong:默认
weak:多用于ui和解决循环引用
copy:用于NSString和Block
assign:非OC对象
既然NSString属于OC对象,那么我们先不使用Copy修饰,在ARC模式下,声明的属性默认是strong修饰,接下来就演示strong修饰NSString的后果
先定义一个AMPerson类,如下:
@interface AMPerson : NSObject
@property (strong,nonatomic)NSString *name;
@end
在控制器中的viewDidLoad方法中编辑如下代码:
AMPerson *p = [[AMPerson alloc] init];
NSMutableString *str = [NSMutableString string];
[str appendString:@"anmav"];
p.name = str;
[str appendString:@"yc"];
NSLog(@"%@",p.name);
打印结果为:anmavyc
结果分析: 如果使用strong修复NSString类型属性,p.name 指向可变字符串对象的地址,当可变字符串内容发生变化时,p.name相对应的也发生变化。
使用copy修饰后,将可变字符串重新拷贝一份,重新开辟内存空间,修改mutableString的值,不会对p.name造成影响。
刚刚的演示,我使用了NSMutableString(可变字符串),对mutableString执行copy操作,属于深拷贝,所以开辟的新内存空间,如果使用的是NSString(不可变内存),对NSString进行copy属于浅拷贝,不会开辟新的内存空间,是不是就不会出现这个问题了呢?
AMPerson *p = [[AMPerson alloc] init];
NSString *str = [NSString string];
str = @"anmav";
p.name = str;
str = @"yc";
NSLog(@"%@",p.name);
打印结果为:anmav
将之前的可变字符串变为不可变字符串,因为NSString不支持append添加操作,我这里的两次str赋值操作,其实是让str重新指向了一片内存空间,并不是修改了str原本内存中的值
(OC中对象即指针,实际上存储的是内存地址,p.name = str; 实际是将str存储的@"xiaoming"这块地址给了p.name,p.name还指向着@"xiaoming")
所以改变str的指向后,p.name的指向并没有改变,输出没有受到影响