NSString copy和strong 的區(qū)別

作為一個有好幾年的開發(fā)人員來說,有時候我們知道怎么用,但是不知道為什么要這么用,也就是知其然,不知其所以然,對于以前的我來說我是一個不求甚解的人。但是作為一個專業(yè)的技術人,要想更上一層樓。還是要知其所以然的為好,特別是技術面試,就能決定一個人的內(nèi)力到底有多深了。

實戰(zhàn)

首先我們創(chuàng)建兩個屬性,一個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 內(nèi)容內(nèi)存首地址
    // %p &str 變量str內(nèi)存的首地址
    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沒區(qū)別)
不管是strong還是copy屬性的對象,其指向的地址都是同一個,即為string指向的地址。
當string的值發(fā)生改變時,兩個對象的值也保持原來的值

第二種情況

- (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,可以根據(jù)實際情況來定。不過,一般我們將對象聲明為NSString時,都不希望它改變,所以大多數(shù)情況下,我們建議用copy,以免因可變字符串的修改導致的一些非預期問題。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容