Objective - C 一一 NSString什么时候用copy,什么时候用strong

我们在声明一个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




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

white camel

感谢支持~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值