retain 和copy的區別
在ios開發中我們一般都這麼定義:@property (nonatomic,copy) NSString *name,而不這麼定義:@property (nonatomic,retain) NSString *name,兩者的差別就在一個使用copy,一個使用retain。
一直以來都不明白為什麼,今天通過查閱資料總算弄明白了,所以記錄一下。
在說明白retain和copy的區別,首先需要明白深複製和淺複製的概念。
1 深複製:內容拷貝,源物件和副本物件指的是兩個不同的物件,源物件引用計數器不變,副本物件引用計數器為1
2 淺複製:指標拷貝,源物件和副本物件指的都是同一個物件,物件引用計數器+1,相當於retain
只有不可變物件建立不可變副本(copy)才是淺複製,其它的都是深複製
上面的結論至關重要,大家可以對NSString和NSMutableString分別測試,在此不再贅述。
下面通過實驗來說明copy和retain的區別。
@interface ViewController ()
@property (nonatomic,copy) NSString *name;
@property (nonatomic,retain) NSString *name2;
@end
-(void)test{
NSString *str = @"fffff";
self.name = str;
self.name2 = str;
NSLog(@" str: %p",str);
NSLog(@" copy: %p",self.name);
NSLog(@"retain: %p",self.name2);
}
-(void)test2{
NSMutableString *str = [NSMutableString stringWithString:@"ffffff"];
self.name = str;
self.name2 = str;
NSLog(@" strM: %p",str);
NSLog(@" copy: %p",self.name);
NSLog(@"retaini: %p",self.name2);
}
先執行test,再執行test2,兩次執行的結果如下:
所以得出結論:
(1)copy是建立一個新物件,兩個物件內容相同,舊物件沒有變化。新的物件retain為1,與舊有物件的引用計數不變。舊物件發生改變不影響新物件,copy減少物件對上下文的依賴。
(2)retain屬性表示兩個物件地址相同(建立一個指標,指標拷貝),內容相同,這個物件的retain值+1。兩個物件要改變就一起改變。
(3)如果把一個物件賦值給另一個物件(如上面把str賦值給name或name2),如果該物件是不可變的,那麼另一個物件是copy或者retain都可以,沒區別;把一個物件賦值給另一個物件,如果該物件是可變的,並且希望另一個物件隨著該物件變化而變化,則可以把另一個物件設定為retain(如上面把str賦值給name2);如果希望另一個物件不隨著該物件變化而變化,則可以把另一個物件設定為copy(如上面把str賦值給name)
相關文章
- iOS strong和copy的區別iOS
- Why should we copy blocks rather than retain?BloCAI
- IOS基礎:retain,copy,assign及autoreleaseiOSAI
- Copy 與MutableCopy的區別
- 集合使用copy與mutableCopy的區別
- iOS之property裡的copy、strong區別iOS
- 深拷貝和淺拷貝 copy與strong修飾變數的區別變數
- 被無數人寫過的assign,retain,strong,weak,unsafe_unretained,還有copyAI
- ../和./和/的區別
- 區分copy構造與copy賦值賦值
- 和 的區別
- as 和 with的區別
- LinkedList和ArrayList的區別、Vector和ArrayList的區別
- http和https的區別/get和post的區別HTTP
- 正確使用Block避免Cycle Retain和CrashBloCAI
- ./ 和sh 的區別
- JQuery this和$(this)的區別jQuery
- jquery $(this) 和this的區別jQuery
- T和?的區別
- ++a和a++的區別
- makefile =和:=的區別
- Mybatis中#{}和${}傳參的區別及#和$的區別小結MyBatis
- Rust中的Copy和CloneRust
- 和區別
- 記憶體管理Release和Retain實現原理記憶體AI
- MYSQL和SQL的區別MySql
- varchar和char的區別
- &self 和 self 的區別
- var和public的區別
- filter和interceptor的區別Filter
- useEffect 和 useLayoutEffect 的區別
- SDK和API的區別?API
- var 和 let 的區別
- WebApi和MVC的區別WebAPIMVC
- service和systemctl的區別
- GET和POST的區別?
- GET和POST的區別
- button和submit的區別MIT