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等同理.