Copy,Strong的區別需要了解點內存管理的知識,Strong是ARC下引入的修飾,相當於手動管理內存(MRC)下的retain,在相關代碼下,常常看到有的人用copy修飾NSString,NSArray,NSDictionary..等存在可變與不可變之分的對象,常常會用copy,而不是strong,下面代碼來解釋一下strong與copy的區別:
先說明一下什麼叫做淺拷貝,什麼叫做深拷貝;
淺Copy:可以理解為指針的復制,只是多了一個指向這塊內存的指針,共用一塊內存。
深Copy:理解為內存的復制,兩塊內存是完全不同的,也就是兩個對象指針分別指向不同的內存,互不干涉。
首先在類延展中聲明兩個屬性變量
@property(nonatomic,strong)NSString*stringStrong;//strong修飾的字符串對象
@property(nonatomic,copy)NSString*stringCopy;//copy修飾的字符串對象
接著創建兩個不可變字符串(NSString)
//新創建兩個NSString對象
NSString*strong1=@"IamStrong!";
NSString*copy1=@"IamCopy!";
將兩個屬性分別進行賦值
//初始化兩個字符串
self.stringStrong=strong1;
self.stringCopy=copy1;
分別打印一下四個變量的內存地址:
NSLog(@"strong1=%p",strong1);
NSLog(@"stringStrong=%p",self.stringStrong);
NSLog(@"copy1=%p",copy1);
NSLog(@"stringCopy=%p",self.stringCopy);
結果如下:可以看出,此時無論是strong修飾的字符串還是copy修飾的字符串,都進行了淺Copy.
2016-02-2918:59:06.332StrongOrCopy[5046:421886]strong1=0x10a0b3078
2016-02-2918:59:06.332StrongOrCopy[5046:421886]stringStrong=0x10a0b3078
2016-02-2918:59:06.332StrongOrCopy[5046:421886]copy1=0x10a0b3098
2016-02-2918:59:06.332StrongOrCopy[5046:421886]stringCopy=0x10a0b3098
如果創建兩個不可變字符串對象(NSMutableString)呢
//新創建兩個NSMutableString對象
NSMutableString*mutableStrong=[NSMutableStringstringWithString:@"StrongMutable"];
NSMutableString*mutableCopy=[NSMutableStringstringWithString:@"CopyMutable"]; 分別對屬性再次進行賦
self.stringStrong=mutableStrong;
self.stringCopy=mutableCopy;
分別打印一下四個變量的地址:結果如下:這時就發現了,用strong修飾的字符串依舊進行了淺Copy,而由copy修飾的字符串進行了深Copy,所以mutableStrong與stringStrong指向了同一塊內存,而mutableCopy和stringCopy指向的是完全兩塊不同的內存。
2016-02-2918:59:06.332StrongOrCopy[5046:421886]mutableStrong=0x7fccba425d60
2016-02-2918:59:06.332StrongOrCopy[5046:421886]stringStrong=0x7fccba425d60
2016-02-2918:59:06.332StrongOrCopy[5046:421886]mutableCopy=0x7fccba40d7c0
2016-02-2918:59:06.333StrongOrCopy[5046:421886]stringCopy=0x7fccba4149e0
那麼有什麼用呢,實例來看一下有什麼區別:
首先是對不可變字符串進行操作:
[objc]view plaincopy
//新創建兩個NSString對象
NSString*strong1=@"IamStrong!";
NSString*copy1=@"IamCopy!";
//初始化兩個字符串
self.stringStrong=strong1;
self.stringCopy=copy1;
//兩個NSString進行操作
[strong1stringByAppendingString:@"11111"];
[copy1stringByAppendingString:@"22222"]; 分別對在字符串後面進行拼接,當然這個拼接對原字符串沒有任何的影響,因為不可變自字符串調用的方法都是有返回值的,原來的值是不會發生變化的.打印如下,對結果沒有任何的影響:
2016-02-2919:15:26.729StrongOrCopy[5146:439360]strong1=IamStrong!
2016-02-2919:15:26.729StrongOrCopy[5146:439360]stringStrong=IamStrong!
2016-02-2919:15:26.729StrongOrCopy[5146:439360]copy1=IamCopy!
2016-02-2919:15:26.729StrongOrCopy[5146:439360]stringCopy=IamCopy!
然後是對可變字符串進行操作:
//新創建兩個NSMutableString對象
NSMutableString*mutableStrong=[NSMutableStringstringWithString:@"StrongMutable"];
NSMutableString*mutableCopy=[NSMutableStringstringWithString:@"CopyMutable"];
//初始化兩個字符串
self.stringStrong=mutableStrong;
self.stringCopy=mutableCopy;
//兩個MutableString進行操作
[mutableStrongappendString:@"Strong!"];
[mutableCopyappendString:@"Copy!"];
再來看一下結果:對mutableStrong進行的操作,由於用strong修飾的stringStrong沒有進行深Copy,導致共用了一塊內存,當mutableStrong對內存進行了操作的時候,實際上對stringStrong也進行了操作; 相反,用copy修飾的stringCopy進行了深Copy,也就是說stringCopy與mutableCopy用了兩塊完全不同的內存,所以不管mutableCopy進行了怎麼樣的變化,原來的stringCopy都不會發生變化.這就在日常中避免了出現一些不可預計的錯誤。
2016-02-2919:20:27.652StrongOrCopy[5245:446189]stringStrong=StrongMutableStrong!
2016-02-2919:20:27.652StrongOrCopy[5245:446189]mutableStrong=StrongMutableStrong!
2016-02-2919:20:27.652StrongOrCopy[5245:446189]stringCopy=CopyMutable
2016-02-2919:20:27.652StrongOrCopy[5245:446189]mutableCopy=CopyMutableCopy!
這樣看來,在不可變對象之間進行轉換,strong與copy作用是一樣的,但是如果在不可變與可變之間進行操作,那麼樓主比較推薦copy,這也就是為什麼很多地方用copy,而不是strong修飾NSString,NSArray等存在可變不可變之分的類對象了,避免出現意外的數據操作.