iOS 屬性中strong,weak,assign,retain,copy等特性
導語:
在初學iOS的時候,不明白property中屬性有什麼作用,比如strong, weak, assign, retain, copy等特性。
一、 Objective-C程式設計師的基本記憶體管理模型有三種
- 自動垃圾收集(現在Apple不建議使用垃圾收集,建議使用ARC進行代替)
- 手動引用計數和自動釋放池
- 自動引用計數(ARC, Xcode4.2釋出了自動引用計數之後,我們幾乎可以不再需要考慮記憶體管理的問題)
二、 手工管理記憶體計數
如果不打算使用ARC,就得學習引用計數工作的原理
當建立一個物件時,初始的引用計數為1,為儲存物件的存在,每當建立引用 -> 物件需要將引用數加1,通過給物件傳送retain訊息實現,當不需要物件時,通過傳送release,為引用計數減1。當物件的引用計數為0時,系統就會釋放它的記憶體。(釋放記憶體由系統的自動釋放池來實現,我們所需要做得主要就是對引用加1減1操作)
[myFraction retain]; //引用計數加1
//中間一系列對myFraction的操作
[myFraction release]; //引用計數減1
在手動引用計數環境中,可以新增assign,retain,copy特性
當我們使用以下這條命令時
self.property = newValue;
assign特性會是:
property = newValue;
assign用於簡單賦值,不更改索引計數
對基礎資料型別 (例如NSInteger,CGFloat)和C資料型別(int, float, double, char, 等)適用簡單資料型別
retain特性會是:
if (property != newValue){
[property release];
property = [newValue retain];
}
retain:釋放舊的物件,將舊物件的值賦予輸入物件,再提高輸入物件的索引計數為1
此屬性只能用於Objective-C物件型別,而不能用於Core Foundation物件。
copy特性會是:
if (property != newValue){
[property release];
property = [newValue copy];
}
copy:建立一個索引計數為1的物件,然後釋放舊物件,在賦值時使用傳入值的一份拷貝。
三、自動引用計數(ARC)
- 強變數(strong)
相當於老版本的retain,而且可以不再需要做release操作了
只要有強變數的引用,物件就不會釋放記憶體。
2.弱變數(weak)
相當於老版本的assign。但是隻適應於物件
當弱變數引用的物件被別的變數釋放,那麼弱變數會被自動設定為nil,這樣可以有效地防止崩潰
3.strong 和 copy的區別
// on someObject:
@property (nonatomic, strong) NSString *text;
@@property (nonatomic, copy) NSString *textTwo;
//省略
. . .
NSMutableString *m = [NSMutableString stringWithString:@"Strawberry"];
someObject.text = m;
someObject.textTwo = m;
// at this point, someObject.text is @"Strawberry"
[m appendString:@" and banana"];
// now both m and someObject.text are @"Strawberry and banana",but someObject.textTwo is still @"Strawberry"
因為執行someObject.text = m時,實際上是把指標指向了m所指向的物件,所以m和someObject.text指標指向同一個物件。
而someObject.textTwo則是先將m中的物件copy了一份,然後再指向這個copy,所以並不會因為m變化而變化。
注意上文說的copy特性,是建立一個索引為1的物件。
4. 如果是新手,實在要用strong特性來申請NSString。那必須注意以下程式碼
someObject.text = [[NSString alloc] initWithString:m];
//這行程式碼的意思就是申請一個新的NSString指標,然後指向一個string值和m值相同的物件。類似copy特性
四、總結
(在ARC環境下)
- 對基礎資料型別 (例如NSInteger,CGFloat)和C資料型別(int, float, double, char, 等)適合用assign特性
- 對於NS開頭,UI開頭的物件引用 比如(NSMutableArray *,NSMutableDictionary * ,NSMutableString *,UIImage *, UIColor *等)可以用strong特性
- 對於NSArray、NSDictionary、NSString最好用copy型別。
- 對UI控制元件的引用,iOS會自動將其設定為弱變數(weak)。