Objective-C內(nèi)存管理教程和原理剖析(二)口訣與范式
口訣與范式
1.口訣。
1.1誰創(chuàng)建,誰釋放(類似于“誰污染,誰治理”)。如果你通過alloc、new或copy來創(chuàng)建一個(gè)對象,那么你必須調(diào)用release或autorelease。換句話說,不是你創(chuàng)建的,就不用你去釋放。
例如,你在一個(gè)函數(shù)中alloc生成了一個(gè)對象,且這個(gè)對象只在這個(gè)函數(shù)中被使用,那么你必須在這個(gè)函數(shù)中調(diào)用release或autorelease。如果你在一個(gè)class的某個(gè)方法中alloc一個(gè)成員對象,且沒有調(diào)用autorelease,那么你需要在這個(gè)類的dealloc方法中調(diào)用release;如果調(diào)用了autorelease,那么在dealloc方法中什么都不需要做。
1.2除了alloc、new或copy之外的方法創(chuàng)建的對象都被聲明了autorelease。
1.3誰retain,誰release。只要你調(diào)用了retain,無論這個(gè)對象是如何生成的,你都要調(diào)用release。有時(shí)候你的代碼中明明沒有retain,可是系統(tǒng)會(huì)在默認(rèn)實(shí)現(xiàn)中加入retain。不知道為什么蘋果公司的文檔沒有強(qiáng)調(diào)這個(gè)非常重要的一點(diǎn),請參考范式2.7和第三章。
2.范式。
范式就是模板,就是依葫蘆畫瓢。由于不同人有不同的理解和習(xí)慣,我總結(jié)的范式不一定適合所有人,但我能保證照著這樣做不會(huì)出問題。
2.1創(chuàng)建一個(gè)對象。
- ClassA *obj1 = [[ClassA alloc] init];
2.2創(chuàng)建一個(gè)autorelease的對象。
- ClassA *obj1 = [[[ClassA alloc] init] autorelease];
2.3Release一個(gè)對象后,立即把指針清空。(順便說一句,release一個(gè)空指針是合法的,但不會(huì)發(fā)生任何事情)
- [obj1 release];
- obj1 = nil;
2.4指針賦值給另一個(gè)指針。
- ClassA *obj2 = obj1;
- [obj2 retain];
- //do something
- [obj2 release];
- obj2 = nil;
2.5在一個(gè)函數(shù)中創(chuàng)建并返回對象,需要把這個(gè)對象設(shè)置為autorelease
- ClassA *Func1()
- {
- ClassA *obj = [[[ClassA alloc]init]autorelease];
- return obj;
- }
2.6在子類的dealloc方法中調(diào)用基類的dealloc方法
- -(void) dealloc
- {
- …
- [super dealloc];
- }
2.7在一個(gè)class中創(chuàng)建和使用property。
2.7.1聲明一個(gè)成員變量。
- ClassB *objB;
2.7.2聲明property,加上retain參數(shù)。
- @property (retain) ClassB* objB;
2.7.3定義property。(property的默認(rèn)實(shí)現(xiàn)請看第三章)
- @synthesize objB;
2.7.4除了dealloc方法以外,始終用.操作符的方式來調(diào)用property。
self.objB 或者objA.objB
2.7.5在dealloc方法中release這個(gè)成員變量。
- [objB release];
示例代碼如下(詳細(xì)代碼請參考附件中的memman-property.m,你需要特別留意對象是在何時(shí)被銷毀的。):
- @interface ClassA : NSObject
- {
- ClassB* objB;
- }
- @property (retain) ClassB* objB;
- @end
- @implementation ClassA
- @synthesize objB;
- -(void) dealloc
- {
- [objB release];
- [super dealloc];
- }
- @end
2.7.6給這個(gè)property賦值時(shí),有手動(dòng)release和autorelease兩種方式。
- 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