修饰NSString属性,Copy or Strong?

2018-04-11  本文已影响14人  忆昔溪

上次面试中,面试官问的问题,我总是习惯于使用Copy,但是里面究竟有什么区别,我没有很好的表达出来,这次通过几个简单的测试,直观的展示Copy和Strong的区别

@property (nonatomic, strong) NSString *sString;
@property (nonatomic, copy) NSString *cString;
- (void)test1 {
    NSString *testStr1 = @"测试1";
    self.sString = testStr1;
    self.cString = testStr1;
    
    NSLog(@"%@, %p, %p", testStr1, testStr1, &testStr1);
    NSLog(@"%@, %p, %p", _sString, _sString, &_sString);
    NSLog(@"%@, %p, %p", _cString, _cString, &_cString);
}

结果表明:不管是Strong还是Copy属性的对象,指向的地址都是testStr1指向的地址。如在MRC环境,输出testStr1的引用计数,会看到其引用计数值是3,即Strong操作和Copy操作都会使原字符串对象的引用计数值加了1。


- (void)test2 {
    NSMutableString *testStr2 = @"测试2".mutableCopy;
    self.sString = testStr2;
    self.cString = testStr2;
    
    NSLog(@"%@, %p, %p", testStr2, testStr2, &testStr2);
    NSLog(@"%@, %p, %p", _sString, _sString, &_sString);
    NSLog(@"%@, %p, %p", _cString, _cString, &_cString);
}

结果表明:此时Copy属性字符串已不再指向原来String对象,而是深拷贝了testStr2字符串,且cString对象指向这个字符串。在MRC环境下,输出两者的引用计数,可以看到String对象的引用计数是2,而cString对象的引用计数是1。


- (void)test3 {
    NSMutableString *testStr3 = @"测试3".mutableCopy;
    self.sString = testStr3;
    self.cString = testStr3;
    
    NSLog(@"%@, %p, %p", testStr3, testStr3, &testStr3);
    NSLog(@"%@, %p, %p", _sString, _sString, &_sString);
    NSLog(@"%@, %p, %p", _cString, _cString, &_cString);
    
    NSLog(@"-----------------------------");
    [testStr3 appendString:@"_修改"];
    
    NSLog(@"%@, %p, %p", testStr3, testStr3, &testStr3);
    NSLog(@"%@, %p, %p", _sString, _sString, &_sString);
    NSLog(@"%@, %p, %p", _cString, _cString, &_cString);
}

结果表明:修改原始可变字符串testStr3话,可以看到,因为sString与原始testStr3是指向同一对象,所以sString的值也会跟随testStr3改变(此时sString的类型实际上是NSMutableString,而不是NSString),而cString是指向另一个对象,并不会改变。


最后结论

上一篇下一篇

猜你喜欢

热点阅读