【面試題】為什么字符串用copy修飾


1.

假如有一個NSMutableString,現在用他給一個retain修飾 NSString賦值,那么只是將NSString指向了NSMutableString所指向的位置,並對NSMUtbaleString計數器加一,此時,如果對NSMutableString進行修改,也會導致NSString的值修改,原則上這是不允許的. 如果是copy修飾的NSString對象,在用NSMutableString給他賦值時,會進行深拷貝,及把內容也給拷貝了一份,兩者指向不同的位置,即使改變了NSMutableString的值,NSString的值也不會改變.

所以用copy是為了安全,防止NSMutableString賦值給NSString時,前者修改引起后者值變化而用的.

 2

我這樣說你就明白了 A->B A中的一個MutableString給B中的一個Property(NSString類型)賦值 首先是能接受的,父類可以接受子類,如果是retain,僅僅是生成一個指針,計數器加一,然后指向那個MutableString。如果MString改變,B中那個跟着改變,因為是同一塊內存區域。而選擇Copy相當於又生成了一個NSString,與A中的MutableString獨立。 

 3.

下面我想通過一個最簡單的例子來說明它們的區別:

首先我們來看看使用strong會出現什么樣的情況:

.h

@property (nonatomic, strong) NSString *name;

.m

NSMutableString *mStr = [NSMutableString stringWithString:@"張三"];

self.name = mStr;

NSLog(@"使用strong第一次得到的名字:%@", self.name);

[mStr appendString:@"豐"];

NSLog(@"使用strong第二次得到的名字:%@", self.name);

打印結果:

2017-04-07 16:20:10.138793 copyTest[2421:682898]使用strong第一次得到的名字:張三

2017-04-07 16:20:10.138884 copyTest[2421:682898]使用strong第二次得到的名字:張三豐

結論:

通過上面的例子我們可以看出,我們在沒有直接修改 self.name 的情況下 self.name 卻被修改了,就好像一個人的名字怎么能沒有經過自己同意就被修改呢?我們的初衷只是想修改mStr,但是 self.name 卻被意外的修改了,而這就是我們使用strong所不想看到的,它會破壞程序的封裝性。(使用strong后 self.name 和 mStr 指向的是同一片內存,所以修改其中一個值后兩個值就都變了)

那么使用copy又會得到什么結果呢?下面是使用copy的例子:

.h

@property (nonatomic, copy) NSString *name;

.m

NSMutableString *mStr = [NSMutableString stringWithString:@"張三"];

self.name = mStr;

NSLog(@"使用copy第一次得到的名字:%@", self.name);

[mStr appendString:@"豐"];

NSLog(@"使用copy第二次得到的名字:%@", self.name);

打印結果:

2017-04-07 16:35:04.012589 copyTest[2428:685221]使用copy第一次得到的名字:張三

2017-04-07 16:35:04.012676 copyTest[2428:685221]使用copy第二次得到的名字:張三

結論:

這個例子中我們使用了copy修飾,mStr通過copy得到了一個新的對象賦值給 self.name 這樣我們再修改mStr就跟 self.name 沒關系了,只有直接對 self.name 進行賦值才能改變它的值,這樣就保證了程序的封裝性。

為什么使用copy而不是strong以上只是一個例子,還有很多情況可以自己去試試,並且可以把屬性類型改成NSMutableString進行不同情況的研究,也可以更加深入理解深拷貝和淺拷貝的含義。

 4.

copy會重新生成一個string,被copy的對象發生改變時,copy后的對象不改變
strong僅僅進行強引用確保持有string的對象在生存期間這個string不會被釋放

題主說的問題有點問題,應該是NSString用copy或strong都可以,下面分場景說:

  • 必須使用copy的場景:A對象持有string記做A.string,然后賦值給B對象,記做B.string,若希望B.string的內容改變時A.string不改變就必須用copy
  • 必須用strong的場景:若希望B.string的內容改變時同時A.string也改變則必須用strong
  • 隨便用哪個的場景:string的內容不會被改變的情況下

以上規則不止適用於NSString,NSArray,NSDictionary等同理.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM