Objective

来源:互联网 发布:博彦科技数据分析师 编辑:程序博客网 时间:2024/06/09 16:39

我们在声明一个NSString属性时,对于其内存相关特性,通常有两种选择(基于ARC环境):strong与copy。那这两者有什么区别呢?什么时候该用strong,什么时候该用copy呢?

首先举个例子:

这里有一个person类,有一个使用cooy的NSString属性.

毋庸置疑的是,字符串属性使用copy,当外界修改了字符串,里面不会改变.


在ViewController.m文件中

注意: 此时的NSString属性name是使用copy的.

- (void)viewDidLoad {    [super viewDidLoad];        // 不可变字符串    NSString *nameStr = @"zy";        Person *person = [[Person alloc] init];        person.name = nameStr;        NSLog(@"%p ---- %p",nameStr,person.name);        }


输出结果:

2017-08-31 18:17:20.992 NSSting_copy_strong[4661:196852] 0x10bbea070 ---- 0x10bbea070


因为NSString是不可变字符串,当使用copy的时候,不会生成一个新的对象,因为源对象是不可更改的对象,那么拷贝出来的也是不可更改的对象,两者互不影响.所以不会产生新的对象.


当把NSString的属性改为strong,此时仍使用NSString不可变字符串.打印结果如下:

2017-08-31 18:23:36.487 NSSting_copy_strong[4747:199526] 0x103e44068 ---- 0x103e44068

所以,在不可变字符串的情况下,无论使用strong,还是copy.其地址指向的都是同一块存储空间.


注意: 当把.m文件中的NSString不可变字符串改为可变字符串之后.

此时NSString的属性使用的strong.

- (void)viewDidLoad {    [super viewDidLoad];        // 可变字符串    NSMutableString *nameStr = [NSMutableString stringWithFormat:@"zy"];        Person *person = [[Person alloc] init];        person.name = nameStr;        NSLog(@"%p ---- %p",nameStr,person.name);        }

输出结果:

2017-08-31 18:27:05.561 NSSting_copy_strong[4845:202200] 0x6000000747c0 ---- 0x6000000747c0

而把NSString的属性改为copy后.

输出结果:

2017-08-31 18:29:07.405 NSSting_copy_strong[4900:203652] 0x600000268a40 ---- 0xa0000000000797a2

此时copy属性的字符串已经不再指向nameStr的内存地址了.而是深拷贝了一份内存地址,并让 _name属性指向这块内存地址.



当源字符串是NSString的时候,无论使用strong,copy属性的对象,都会指向源对象,此时copy只是做了一次浅拷贝.

当源字符串是NSSMutableString的时候,copy属性对源字符串做了一次深拷贝,创建了一个新的对象,并指向新对象的内存地址.


注意: 

一般情况下我们在开发中使用的大多数都是NSString不可变字符串.在网络中加载的数据大多也是不可变的.当使用不可变字符的时候,strong,copy都不会产生新的对象.这个时候建议使用strong;原因如下:

当NSString属性使用copy的时候.

@property (nonatomic, copy) NSString *name;
此时name的set方法是这样的.

// copy情况下的属性name的set方法- (void)setName:(NSString *)name{    _name = [name copy];}
在set方法中,每次都会去判断name是NSString的还是NSMutableString的.如果是NSString不可变字符串的时候,就不会去生成新的对象,如果是可变字符串,就会去生成新的对象.这样会进行一次判断操作.


当NSString属性使用strong的时候

@property (nonatomic, strong) NSString *name;
此时name的set方法是这样的
// strong情况下的属性name的set方法- (void)setName:(NSString *)name{    _name = name;}


在set方法中不用去判断,外界传入的可变或不可变字符.这样提高了性能.所以当外界传入的字符串是NSString不可变字符串的时候,建议使用strong.


关于本章内容比较好的博文: http://www.cocoachina.com/ios/20150512/11805.html




原创粉丝点击