NSString用copy还是strong修饰?

strong修饰

  • 要给属性NSString赋一个不可变的值时,用strong

缘由:
如果使用copy来修饰属性,在进行赋值的时候,会先做一个类型判断,如果赋的值是一个不可变的字符串,则走strong的策略,进行的是浅拷贝;如果是可变的字符串,则进行深拷贝创建一个新的对象。所以如果我们确定是给属性赋值一个不可变的值,就不用copy再多去判断一遍类型,因为如果是很多的NSString属性需要赋值,会极大的增加系统开销。所以用strong在此情况下可以提升性能

代码示例:
声明两个变量

@property (nonatomic, strong) NSString *strongString;
@property (nonatomic, copy) NSString *copyedString;
不可变字符串赋值
- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSString *string = [NSString stringWithFormat:@"lalala"];
    self.strongString = string;
    self.copyedString = string;
    NSLog(@"origin string: %p, %p", string, &string);
    NSLog(@"strong string: %p, %p", _strongString, &_strongString);
    NSLog(@"copyed string: %p, %p", _copyedString, & _copyedString);
    
    
  }

结果
2019-08-30 14:22:00.546434+0800 test[1150:566116] origin string: 0x9c1dc136cdff7947, 0x7ffee0870a88
2019-08-30 14:22:01.756447+0800 test[1150:566116] strong string: 0x9c1dc136cdff7947, 0x7fd4eb70a3e0
2019-08-30 14:22:02.937356+0800 test[1150:566116] copyed string: 0x9c1dc136cdff7947, 0x7fd4eb70a3e8

换成

  NSString *string = [NSString stringWithFormat:@"lalala"];
    _strongString = string;
    _copyedString = string;
    NSLog(@"origin string: %p, %p", string, &string);
    NSLog(@"strong string: %p, %p", _strongString, &_strongString);
    NSLog(@"copyed string: %p, %p", _copyedString, & _copyedString);

结果一样

2019-08-30 14:24:09.758115+0800 test[2070:572063] origin string: 0xaae3606a066107fb, 0x7ffee36c9a88
2019-08-30 14:24:09.758307+0800 test[2070:572063] strong string: 0xaae3606a066107fb, 0x7fed62602c60
2019-08-30 14:24:09.758403+0800 test[2070:572063] copyed string: 0xaae3606a066107fb, 0x7fed62602c68

结论

  • 对于不可变的字符串修饰不管是strong还是copy属性的对象,其指向的地址都是同一个,即为string指向的地址。

copy修饰

前提我们用self.name

  • 修饰可变的字符串,当它发生变化时,用strong修饰的属性会发生变化,而copy修饰是深拷贝,不会发生变化。
  • 当可变字符串赋值我们希望,值不变用strong 都是指向同一个地址
  • 当可变字符串赋值我们希望,值改变,创建一个新的对象,用copy(调用用self.name)
  • 但是大多数情况下我们不确定是可变的还是不可变的使用copy来修饰,这样保证了安全性

代码示例:

 NSMutableString *mutbleString = [NSMutableString stringWithFormat:@"hahaha"];
    self.strongString = mutbleString;
    self.copyedString = mutbleString;
    [mutbleString appendString:@" wawawa"];

结果

2019-08-30 15:09:26.257451+0800 test[15589:652086] origin string: 0x6000028e0c00, 0x7ffeebc10a88
2019-08-30 15:09:26.257633+0800 test[15589:652086] strong string: 0x6000028e0c00, 0x7ff4e8c09320
2019-08-30 15:09:26.257731+0800 test[15589:652086] copyed string: 0xcebcae1ddfc2b804, 0x7ff4e8c09328

在这里插入图片描述

结论:
当我们赋值时用self 这时候strong 修饰的字符串和可变的字符串指向同一个对象,而copy 修饰的时候发生了变化,是深拷贝创建了一个新的对象,所以,当可变字符串发生改变时,strong 修饰的也会发生改变,但是copy 修饰的不会发生改变,。

代码示例

 NSMutableString *mutbleString = [NSMutableString stringWithFormat:@"hahaha"];
    _strongString = mutbleString;
    _copyedString = mutbleString;
    [mutbleString appendString:@" wawawa"];
    NSLog(@"origin string: %p, %p", mutbleString, &mutbleString);
    NSLog(@"strong string: %p, %p", _strongString, &_strongString);
    NSLog(@"copyed string: %p, %p", _copyedString, & _copyedString);

结论

在这里插入图片描述

同样用,strong 和copy 来修饰,但是用self.name 和_.name
结论是不一样的,

用可变的字符串赋值用_name 时这时候指向同一个对象

缘由:

  • self.name 是对属性的访问是调用的name属性的getter/setter方法
  • _name 是对局部变量的访问并不会调用getter/setter方法

总结:self方法实际上是用了get和set方法间接调用,下划线方法是直接对变量操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值