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
- IOS基礎:retain,copy,assign及autoreleaseiOSAI
- 深拷貝和淺拷貝 copy與strong修飾變數的區別變數
- ../和./和/的區別
- LinkedList和ArrayList的區別、Vector和ArrayList的區別
- http和https的區別/get和post的區別HTTP
- ||和??的區別
- /*和/**的區別
- 記憶體管理Release和Retain實現原理記憶體AI
- Rust中的Copy和CloneRust
- jquery $(this) 和this的區別jQuery
- JQuery this和$(this)的區別jQuery
- T和?的區別
- makefile =和:=的區別
- ++a和a++的區別
- ./ 和sh 的區別
- Copy of a Copy of a Copy
- 和區別
- springmvc和springboot的區別SpringMVCSpring Boot
- SDK和API的區別?API
- ArrayList和LinkedList的區別?
- button和submit的區別MIT
- MTV和MVC的區別MVC
- hadoop和spark的區別HadoopSpark
- rpop 和 brpop的區別
- WebApi和MVC的區別WebAPIMVC
- GET和POST的區別?
- ArrayList和LinkedList的區別
- WBS和TASK的區別?
- JavaScript中for in 和for of的區別JavaScript
- innerText 和 textContent 的區別?
- var 和 let 的區別
- @JsonProperty和@JsonAlias的區別JSON
- POST 和 GET 的區別
- sass和less的區別
- MySQL和Oracle的區別MySqlOracle
- sizeThatFits 和 sizeToFit的區別
- GitHub和GitLab的區別GithubGitlab
- Js中for in 和for of的區別JS