美文网首页面试技术
Object-c 关于copy和strong的区别,以及self

Object-c 关于copy和strong的区别,以及self

作者: 煎包小混沌 | 来源:发表于2017-07-16 12:17 被阅读0次

虽然网上有很多解释,但还是自己测试一遍看看结果。
interface定义两个字符串,分别copy和strong修饰

@interface ViewController ()
@property (nonatomic, copy) NSString *strCopy1;
@property (nonatomic, strong) NSString *strStrong1;

1:使用不可变字符串赋值

NSString *str111 = @"name";
    self.strCopy1 = str111,
    self.strStrong1 = str111;
  
    NSLog(@"%p->内存%p-----", &str111, str111);
    NSLog(@"%p->内存%p-----", &_strCopy1, _strCopy1);
    NSLog(@"%p->内存%p-----", &_strStrong1, _strStrong1);
结果:
2017-07-16 11:21:57.305 strong-copy[3211:556935] 0x7fff5b10ca08->内存0x104af3078-----
2017-07-16 11:21:57.305 strong-copy[3211:556935] 0x7f841ec051f8->内存0x104af3078-----
2017-07-16 11:21:57.305 strong-copy[3211:556935] 0x7f841ec05200->内存0x104af3078-----

可以看到,三个不同的指针指向同一个内存地址,这里并没有发现copy和strong有什么区别。

2:使用可变字符串赋值

 NSMutableString *str333 = [NSMutableString stringWithFormat:@"qwe"];
    self.strCopy1 = str333;
    self.strStrong1 = str333;
    
    [str333 appendString:@"sss"];
    NSLog(@"%p->内存%p-----%@", &str333, str333, str333);
    NSLog(@"%p->内存%p-----%@", &_strCopy1, _strCopy1, _strCopy1);
    NSLog(@"%p->内存%p-----%@", &_strStrong1, _strStrong1, _strStrong1);
结果
2017-07-16 11:28:52.466 strong-copy[3267:566054] 0x7fff5df88a00->内存0x608000264cc0-----qwesss
2017-07-16 11:28:52.466 strong-copy[3267:566054] 0x7f97a8607f88->内存0xa000000006577713-----qwe
2017-07-16 11:28:52.466 strong-copy[3267:566054] 0x7f97a8607f90->内存0x608000264cc0-----qwesss

发现self.strCopy1执行了深拷贝,而self.strStrong1则依然指向原来的内存地址。

结论:发现copy和strong的区别在于针对可变对象时,copy会深拷贝一个新的内存地址,防止对象再次被修改。

接下里,我们看看self.xxx和_xxx的区别。
大家都知道,当我们使用@property声明对象xxx时,会自动生成一个_xxx的变量,这时发现self.xxx和_xxx都可以调用。但是这两者具体有什么区别?

度娘了一下,发现都有这么一句话:self.xxx是访问属性的,而_xxx是访问实例变量的。

不明白没关系,直接代码测试:

NSMutableString *str333 = [NSMutableString stringWithFormat:@"qwe"];
    _strCopy1 = str333;  //将这里的self.xxx改_xxx
    _strStrong1 = str333;
    
    [str333 appendString:@"sss"];
    NSLog(@"%p->内存%p-----%@", &str333, str333, str333);
    NSLog(@"%p->内存%p-----%@", &_strCopy1, _strCopy1, _strCopy1);
    NSLog(@"%p->内存%p-----%@", &_strStrong1, _strStrong1, _strStrong1);

2017-07-16 11:45:24.625 strong-copy[3325:585666] 0x7fff5e38ea00->内存0x618000074c00-----qwesss
2017-07-16 11:45:24.625 strong-copy[3325:585666] 0x7f818ac08c98->内存0x618000074c00-----qwesss
2017-07-16 11:45:24.625 strong-copy[3325:585666] 0x7f818ac08ca0->内存0x618000074c00-----qwesss

结果发现不论是copy还是strong修饰,使用_xxx赋值的内存地址都没有变化。

结论1:self.xxx会调用set和get的方法,而_xxx不会调用。所有在使用懒加载的时候需要使用self.xxx访问;
结论2:self.xxx和_xxx在引用的时候不会有区别,是同一个指针,但是赋值是有区别的 self.xxx=aa 首先把xxx retaincount -1然后retain aa _xxx复制直接指向oo 不存在retain这一步操作。

总结:1使用@property声明对象时,字符串尽量使用copy修饰;
2使用@property声明对象时,尽量使用self.xxx访问。
当然了,具体情况需要具体对待。

相关文章

网友评论

    本文标题:Object-c 关于copy和strong的区别,以及self

    本文链接:https://www.haomeiwen.com/subject/rgetkxtx.html