您当前的位置: 首页 > 

white camel

暂无认证

  • 1浏览

    0关注

    442博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

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

white camel 发布时间:2017-08-31 18:13:17 ,浏览量:1

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

关注
打赏
1661428283
查看更多评论
立即登录/注册

微信扫码登录

0.0965s