標籤:android des style blog class code
iOS 在 ARC 環境下 dealloc 的使用、理解誤區
太陽火神的美麗人生 (http://blog.csdn.net/opengl_es)
本文遵循“署名-非商業用途-保持一致”創作公用協議
轉載請保留此句:太陽火神的美麗人生 - 本部落格專註於 敏捷開發及移動和物聯裝置研究:iOS、Android、Html5、Arduino、pcDuino,否則,出自本部落格的文章拒絕轉載或再轉載,謝謝合作。
最後一句話,解開了俺接觸 ARC 以來一直的誤解:
在 ARC 環境下,重載的 dealloc 方法一樣會被調用,只不過,不能在該方法的實現中調用父類的該方法。
下面看個樣本來驗證一下:
一個待測試的類 Test,建立和銷毀它,在 ARC 環境下看看 dealloc 是否被調用了;第二就是在 dealloc 中調用父類的實現,看看會怎樣。
另一個是視圖控制器,用於添加兩個按鈕,其中一個按鈕的事件方法用於建立 Test 類,另一個用於釋放,這裡同樣測試了一個 ARC 中當一個對象被 0 個引用指向時,是否馬上釋放。
Test 類的聲明如下:
#import <Foundation/Foundation.h>@interface Test : NSObject@end
Test 類的聲明和實現如下:
#import "Test.h"@implementation Test- (id)init { self = [super init]; if (self) { } return self;}- (void)dealloc { NSLog(@"dealloc"); //[super dealloc];}@end
視圖控制器聲明:
#import <UIKit/UIKit.h>#import "Test.h"@interface ViewController : UIViewController@property (nonatomic, strong) Test *test;@end
視圖控制器實現:
#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad{ [super viewDidLoad];// Do any additional setup after loading the view, typically from a nib.}- (void)didReceiveMemoryWarning{ [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}- (IBAction)generateButtonPressed:(UIButton *)sender { self.test = [[Test alloc] init];}- (IBAction)removeButtonPressed:(UIButton *)sender { self.test = nil;}@end
經測試,一切正常,而且在按釋放按鈕時,Test 類的對象的 dealloc 方法會立即被調用,基本沒有感覺到延遲。
另外,當在 Test 類的 dealloc 方法最後調用父類的 dealloc 方法實現時,XCode 5.1.1 會自動出現提示,如:
ARC 拒絕 顯式 ‘dealloc’ 訊息發送。
至此,下定決心,把 ARC 相關的文檔整理,並每天抽出點業務時間,好好通讀一遍,這個很有必要。
ARC 對我來說,只是憑大概理解就用起來了,一方面確實沒時間,另一方面自我感覺良好,以為理解和掌握了蘋果的架構設計理念,按此一直往下猜,終於鬧出今天的笑話來。
凡事,還是要從官方的資料中求證一下才好,也免於每次用時的為不確定而分心。
“精於計算”首先需要嚴謹;而“精於算計”就不用太過嚴謹,粗獷才不至於束縛。
討論
Discussion
該對象的後續訊息會產生一個錯誤資訊,該資訊指出訊息發送給了一個已釋放的對象(提供了未被重用的已釋放記憶體)。
Subsequent messages to the receiver may generate an error indicating that a message was sent to a deallocated object (provided the deallocated memory hasn’t been reused yet).
你重載該方法用於處理資源,而不是用於處理對象的執行個體變數,例如:
You override this method to dispose of resources other than the object’s instance variables, for example:
- (void)dealloc { free(myBigBlockOfMemory);}
在 dealloc 的實現中,不要調用父類的實現。你應該盡量避勉使用 dealloc 管理有限資源諸如檔案描述符的生命週期。
In an implementation of dealloc, do not invoke the superclass’s implementation. You should try to avoid managing the lifetime of limited resources such as file descriptors usingdealloc.
決不要直接發送 dealloc 訊息。相反,任何對象的 dealloc 方法由運行時調用。參看 進階記憶體管理編程指南 以獲得更詳細的內容。
You never send a dealloc message directly. Instead, an object’sdealloc method is invoked by the runtime. SeeAdvanced Memory Management Programming Guide for more details.
特別注意事項
Special Considerations
當未使用 ARC 時,你的 dealloc 實現必須把調用父類的實現作為最後一條指令。(隱含的意思就是,使用 ARC 時不能調用父類的實現)
When not using ARC, your implementation of dealloc must invoke the superclass’s implementation as its last instruction.