1. Objective-C指针赋值时,retainCount不会自动增长,须要手动retain。数组
1 ClassA *obj1 = [[ClassA alloc] init]; //retain count = 1 2 ClassA *obj2 = obj1; //retain count = 1 3 [obj2 retain]; //retain count = 2 4 [obj1 hello]; //输出hello 5 [obj1 release]; //retain count = 2 – 1 = 1 6 [obj2 relese]; //retain count = 0,对象被销毁
2. 新生成的对象只要调用autorelease就好了,无需再调用release!自动释放的对象不须要调用release,由于已经将释放的责任转交给了自动释放池。可是对于赋值的指针仍是要调用release的!函数
1 ClassA *obj1 = [[[ClassA alloc] init] autorelease]; //retain count = 1 2 ClassA *obj2 = obj1; //retain count = 1 3 [obj2 retain]; //retain count = 2 4 [obj1 hello]; //输出hello 5 //对于obj1,无需调用(实际上不能调用) 6 release [obj2 hello]; //输出hello 7 [obj2 release]; //retain count = 2-1 = 1
3. NSAutoreleasePool内部包含一个数组(NSMutableArray),用来保存声明为autorelease的全部对象。若是一个对象声明为autorelease,系统所作的工做就是把这个对象加入到这个数组中去。NSAutoreleasePool自身在销毁的时候,会遍历一遍这个数组,release数组中的每一个成员。若是此时数组中成员的retain count为1,那么release以后,retain count为0,对象正式被销毁。若是此时数组中成员的retain count大于1,那么release以后,retain count大于0,此对象依然没有被销毁,内存泄露。spa
而自动释放池之间以栈的形式实现:当你建立了一个新的自动释放池时,它被添加到栈顶。接受autorelease消息的对象将被放入最顶端的自动释放池中。若是将一个对象放入一个自动释放池中,而后建立一个新的自动释放池,再销毁新建的自动释放池,则这个自动释放池对象仍将存在,由于容纳该对象的自动释放池仍然存在。指针
4. Objective-C程序中能够嵌套建立多个autorelease pool。在须要大量建立局部变量的时候,能够建立内嵌的autorelease pool来及时释放内存。通常都是使用完对象以后立刻进行释放,以将内存使用量保持在尽量低的水平。code
5. 若是你经过alloc、new或copy来建立一个对象,若是是临时对象,那么你必须在再也不使用时手动调用release或autorelease来释放对象;若是但愿在多段代码中一直拥有对象,做为其余对象的实例来使用,则只需确保在拥有该对象的dealloc方法中释放它便可。除了alloc、new或copy以外的方法建立的对象都被声明了autorelease。orm
6. 谁retain,谁release。只要你调用了retain,不管这个对象是如何生成的,你都要调用release。对象
7. 范式:Release一个对象后,当即把指针清空(顺便说一句,release一个空指针是合法的,但不会发生任何事情)。blog
1 [obj1 release]; 2 obj1 = nil;
1 ClassA *obj2 = obj1; 2 [obj2 retain]; 3 //do something 4 [obj2 release]; 5 obj2 = nil;
8. 范式:在方法中建立的临时对象,在方法返回前须要对其进行释放。事件
在一个函数中建立并返回对象,须要把这个对象设置为autorelease。这样,因为延迟释放,返回的对象不只有效,并且保证会被自动释放池释放。内存
1 ClassA *Func1() 2 { 3 ClassA *obj = [[[ClassA alloc]init]autorelease]; 4 return obj; 5 }
若是程序的某个方法中须要建立不少临时对象,当方法执行完以后这些临时对象就没用了。若是整个程序只有一个释放池,则这些临时对象会一直没法释放,直至事件处理结束。因此,能够在方法的开始处或循环中建立一个局部的自动释放池,在方法返回或退出循环以前释放自动释放池。这样全部该方法建立的临时对象会随着自动释放池的释放而释放。使用@autoreleasePool{},无须显示向某对象发送autorelease方法,全部花括号里的代码都会被自动放入这个新池子里,任何在花括号里定义的变量在括号外就没法使用了。
1 int main (int argc, const char *argv[]) 2 { 3 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 4 int i, j; 5 for (i = 0; i < 100; i++ ) 6 { 7 @autoreleasePool 8 { 9 for (j = 0; j < 100000; j++ ) 10 [NSString stringWithFormat:@"1234567890"];//产生的对象是autorelease的。
12 } 13 } 14 return (0); 15 } // main
9. 范式:在子类的dealloc方法中调用基类的dealloc方法 。
1 -(void) dealloc 2 { 3 … 4 [super dealloc]; 5 }
10. 范式:若是类中声明了具备保持copy和复制retain特性的属性,则须要在dealloc方法中release其成员变量。
1 @interface ClassA : NSObject 2 { 3 ClassB* _objB; 4 } 5 @property (retain) ClassB* objB; 6 @end 7 8 @implementation ClassA 9 @synthesize objB; 10 -(void) dealloc 11 { 12 [_objB release]; 13 [super dealloc]; 14 } 15 @end
11. 范式:除了dealloc方法之外,始终用.操做符的方式来调用property。
1 self.objB 或者 objA.objB
12. 本身管好本身就行。若是得到了一个其余方法提供的对象,则不须要考虑该对象的内存管理问题,没必要执行任何操做。可是,若是想要在一段时间内使用该对象,则须要保留retain该对象,并在使用完成后(在dealloc方法中)将其释放release。必须保持retain方法和release方法的使用次数相等。