口訣與正規化
1. 口訣
1.1 誰建立,誰釋放(類似於“誰汙染,誰治理”)。如果你通過alloc、new或copy來建立一個物件,那麼你必須呼叫release或autorelease。換句話說,不是你建立的,就不用你去釋放。
例如,你在一個函式中alloc生成了一個物件,且這個物件只在這個函式中被使用,那麼你必須在這個函式中呼叫release或autorelease。如果你在一個class的某個方法中alloc一個成員物件,且沒有呼叫autorelease,那麼你需要在這個類的dealloc方法中呼叫release;如果呼叫了autorelease,那麼在dealloc方法中什麼都不需要做。
1.2 除了alloc、new或copy之外的方法建立的物件都被宣告瞭autorelease。
1.3 誰retain,誰release。只要你呼叫了retain,無論這個物件是如何生成的,你都要呼叫release。有時候你的程式碼中明明沒有retain,可是系統會在預設實現中加入retain。不知道為什麼蘋果公司的文件沒有強調這個非常重要的一點,請參考正規化2.7和第三章。
2 正規化
正規化就是模板,就是依葫蘆畫瓢。由於不同人有不同的理解和習慣,我總結的正規化不一定適合所有人,但我能保證照著這樣做不會出問題。
2.1 建立一個物件。
1 |
ClassA *obj1 = [[ClassA alloc] init]; |
2.2 建立一個autorelease的物件。
1 |
ClassA *obj1 = [[[ClassA alloc] init] autorelease]; |
2.3 Release一個物件後,立即把指標清空。(順便說一句,release一個空指標是合法的,但不會發生任何事情)
1 2 3 |
[obj1 release]; obj1 = nil; |
2.4 指標賦值給另一個指標。
1 2 3 4 5 6 7 8 9 |
ClassA *obj2 = obj1; [obj2 retain]; //do something [obj2 release]; obj2 = nil; |
2.5 在一個函式中建立並返回物件,需要把這個物件設定為autorelease
1 2 3 4 5 6 7 8 9 |
ClassA *Func1() { ClassA *obj = [[[ClassA alloc]init]autorelease]; return obj; } |
2.6 在子類的dealloc方法中呼叫基類的dealloc方法
1 2 3 4 5 6 7 8 9 |
-(void) dealloc { … [super dealloc]; } |
2.7 在一個class中建立和使用property。
2.7.1 宣告一個成員變數。
1 |
ClassB *objB; |
2.7.2 宣告property,加上retain引數。
1 |
@property (retain) ClassB* objB; |
2.7.3 定義property。(property的預設實現請看第三章)
1 |
@synthesize objB; |
2.7.4 除了dealloc方法以外,始終用.操作符的方式來呼叫property。
1 |
self.objB 或者objA.objB |
2.7.5 在dealloc方法中release這個成員變數。
1 |
[objB release]; |
示例程式碼如下(詳細程式碼請參考附件中的memman-property.m,你需要特別留意物件是在何時被銷燬的。):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@interface ClassA : NSObject { ClassB* objB; } @property (retain) ClassB* objB; @end @implementation ClassA @synthesize objB; -(void) dealloc { [objB release]; [super dealloc]; } @end |
2.7.6 給這個property賦值時,有手動release和autorelease兩種方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
void funcNoAutorelease() { ClassB *objB1 = [[ClassB alloc]init]; ClassA *objA = [[ClassA alloc]init]; objA.objB = objB1; [objB1 release]; [objA release]; } void funcAutorelease() { ClassB *objB1 = [[[ClassB alloc]init] autorelease]; ClassA *objA = [[[ClassA alloc]init] autorelease]; objA.objB = objB1; } |
示例程式碼檔案連結:http://files.cnblogs.com/VinceYuan/objective-c-memman.zip