美文网首页
NSString copy和strong 的区别

NSString copy和strong 的区别

作者: ikonan | 来源:发表于2018-09-18 22:00 被阅读20次

作为一个有好几年的开发人员来说,有时候我们知道怎么用,但是不知道为什么要这么用,也就是知其然,不知其所以然,对于以前的我来说我是一个不求甚解的人。但是作为一个专业的技术人,要想更上一层楼。还是要知其所以然的为好,特别是技术面试,就能决定一个人的内力到底有多深了。

实战

首先我们创建两个属性,一个copy修饰, 一个strong修饰

@interface ViewController ()
@property(nonatomic, strong) NSString *strongStr;
@property(nonatomic, copy) NSString *copyedStr;

@end

第一种情况

- (void)testOne {
    NSString *str = [NSString stringWithFormat:@"ikonan"];
    self.strongStr = str;
    self.copyedStr = str;

    // %p str 内容内存首地址
    // %p &str 变量str内存的首地址
    NSLog(@"originString: %p, %p, %@",str, &str, str);
    NSLog(@"strongString: %p, %p, %@",_strongStr, &_strongStr, self.strongStr);
    NSLog(@"copyedString: %p, %p, %@",_copyedStr, &_copyedStr, self.copyedStr);
  
    
    str = @"abc";
    NSLog(@"originString: %p, %p, %@",str, &str, str);
    NSLog(@"strongString: %p, %p, %@",_strongStr, &_strongStr, self.strongStr);
    NSLog(@"copyedString: %p, %p, %@",_copyedStr, &_copyedStr, self.copyedStr);
    
//运行结果
 originString: 0xa006e616e6f6b696, 0x16b1a53a8, ikonan
 strongString: 0xa006e616e6f6b696, 0x10520d190, ikonan
 copyedString: 0xa006e616e6f6b696, 0x10520d198, ikonan

 originString: 0x104c600f0, 0x16b1a53a8, abc
 strongString: 0xa006e616e6f6b696, 0x10520d190, ikonan
 copyedString: 0xa006e616e6f6b696, 0x10520d198, ikonan
}
结论

当string为不可变字符串时(这种情况strong 和 copy没区别)
不管是strong还是copy属性的对象,其指向的地址都是同一个,即为string指向的地址。
当string的值发生改变时,两个对象的值也保持原来的值

第二种情况

- (void)testTwo {
    NSMutableString *str = [[NSMutableString alloc] initWithString:@"ikonan"];
    self.strongStr = str;
    self.copyedStr = str;
    
    NSLog(@"originString: %p, %p, %@",str, &str, str);
    NSLog(@"strongString: %p, %p, %@",_strongStr, &_strongStr, self.strongStr);
    NSLog(@"copyedString: %p, %p, %@",_copyedStr, &_copyedStr, self.copyedStr);

    [str appendString:@"123"];
    NSLog(@"originString: %p, %p, %@",str, &str, str);
    NSLog(@"strongString: %p, %p, %@",_strongStr, &_strongStr, self.strongStr);
    NSLog(@"copyedString: %p, %p, %@",_copyedStr, &_copyedStr, self.copyedStr);
}

//运行结果
 originString: 0x1c0252570, 0x16b7f53a8, ikonan
 strongString: 0x1c0252570, 0x14bd07ba0, ikonan
 copyedString: 0xa006e616e6f6b696, 0x14bd07ba8, ikonan

 originString: 0x1c0252570, 0x16b7f53a8, ikonan123
 strongString: 0x1c0252570, 0x14bd07ba0, ikonan123
 copyedString: 0xa006e616e6f6b696, 0x14bd07ba8, ikonan

结论

当string为可变字符串时(copy 深拷贝, strong 就是浅拷贝)

  • 此时copy属性字符串已不再指向string字符串对象,而是深拷贝了string字符串,并让_copyedStr对象指向这个字符串
  • _strongStr与string是指向同一对象,所以_strongString的值也会跟随着改变(需要注意的是,此时_strongStr的类型实际上是NSMutableString,而不是NSString);而_copyedStr是指向另一个对象的,所以并不会改变。

总结

在声明NSString属性时,到底是选择strong还是copy,可以根据实际情况来定。不过,一般我们将对象声明为NSString时,都不希望它改变,所以大多数情况下,我们建议用copy,以免因可变字符串的修改导致的一些非预期问题。

相关文章

网友评论

      本文标题:NSString copy和strong 的区别

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