介紹: ARC是自iOS 5之後增加的新特性,完全消除了手動管理記憶體的煩瑣,編譯器會自動在適當的地方插入適當的retain、release、autorelease語句。你不再需要擔心記憶體管理,因為編譯器為你處理了一切 註意:ARC 是編譯器特性,而不是 ios 運行時特性(除了weak指針系統),它 ...
介紹:
ARC是自iOS 5之後增加的新特性,完全消除了手動管理記憶體的煩瑣,編譯器會自動在適當的地方插入適當的retain、release、autorelease語句。你不再需要擔心記憶體管理,因為編譯器為你處理了一切
註意:ARC 是編譯器特性,而不是 ios 運行時特性(除了weak指針系統),它也不是類似於其它語言中的垃圾收集器。因此 ARC 和手動記憶體管理性能是一樣的,有時還能更加快速,因為編譯器還可以執行某些優化。
原理:
ARC 的規則非常簡單:只要還有一個變數指向對象,對象就會保持在記憶體中。當指針指向新值,或者指針不再存在時,相關聯的對象就會自動釋放。這條規則對於實例變數、synthesize屬性、局部變數都是適用的。
一、Strong 原理:
文本輸入框框屬性
1 @property (nonatomic, assign) IBOutlet UITextField *nameField;
1.在文本框中輸入mj這個字元串
那麼就可以說,nameField的text屬性是NSString對象的指針,也就是擁有者,該對象保存了文本輸入框的內容
2.如果執行瞭如下代碼
1 NSString *name = self.nameField.text;
一個對象可以有多個擁有者,在上面代碼中,name變數同樣也是這個NSString對象的擁有者,也就是有兩個指針指向同一個對象
3.隨後用戶改變了輸入框的內容,比如
此時nameFeild的text屬性就指向了新的NSString對象。但原來的NSString對象仍然還有一個所有者(name變數),因此會繼續保留在記憶體中
4.當name變數獲得新值,或者不再存在時(如局部變數方法返回時、實例變數對象釋放時),原先的NSString對象就不再擁有任何所有者,retain計數降為0,這時對象會被釋放
如,給name變數賦予一個新值
name = @"Jake";
我們稱name和nameField.text指針為"Strong指針",因為它們能夠保持對象的生命。預設所有實例變數和局部變數都是Strong指針
二、Weak 指針
weak型的指針變數仍然可以指向一個對象,但不屬於對象的擁有者
1.執行下麵的代碼
1 __weak NSString *name = self.nameField.text;
name變數和nameField.text屬性都指向同一個NSString對象,但name不是擁有者
2.如果文本框的內容發生變化,則原先的NSString對象就沒有擁有者,會被釋放,此時name變數會自動變成nil,稱為空指針
weak型的指針變數自動變為nil是非常方便的,這樣阻止了weak指針繼續指向已釋放對象,避免了野指針的產生,不然會導致非常難於尋找的Bug,空指針消除了類似的問題
3.weak指針主要用於“父-子”關係,父親擁有一個兒子的strong指針,因此父親是兒子的所有者;但為了阻止所有權迴圈,兒子需要使用weak指針指向父親。典型例子是delegate模式,你的ViewController通過strong指針(self.view)擁有一個UITableView, UITableView的dataSource和delegate都是weak指針,指向你的ViewController
三、strong和weak指針的使用註意
1.下麵的代碼有問題:
1 __weak NSString *str = [[NSString alloc] initWithFormat:@"1234"]; 2 NSLog(@"%@", str); // 列印出來是"(null)"
str是個weak指針,所以NSString對象沒有擁有者,在創建之後就會被立即釋放。Xcode還會給出警告("Warning: Assigning retained object to weak variable; object will be released after assignment")
如:
在AppDelegate.m中
1 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 2 // Override point for customization after application launch. 3 ViewController *vc = [[ViewController alloc] init]; 4 self.window.rootViewController = vc; 5 6 [self.window makeKeyAndVisible]; 7 8 9 return YES; 10 }
在ViewController.h中
1 #import <UIKit/UIKit.h> 2 3 @interface ViewController : UIViewController 4 5 @property(nonatomic, weak) UIView *aView; 6 7 8 @end
在ViewController.m中
用控制台列印:
2.一般的指針變數預設就是strong類型的,因此一般我們對於strong變數不加__strong修飾,以下兩行代碼是等價的:
1 NSString *name = self.nameField.text; 2 __strong NSString *name = self.nameField.text;
3.屬性可以是strong或weak,寫法如下
1 @property (nonatomic, strong) NSString *name; 2 @property (nonatomic, weak) id delegate;
參考資料:ARC-weak和Strong指針