oc内存管理 ---自动释放池
2015-08-15 20:45
513 查看
自动释放池
1、新版的自动内存释放使用@autoreleasepool关键字声明一个代码块,如果一个对象在初始化时调用了autorelease方法,那么当代码块执行完之后在块中调用autorelease方法的对象都会自动调用一次release方法。这样一来就起到了自动释放的作用,同时对象的销毁过程也得到了延迟(统一调用release方法)
2、也有别的版本使用如下格式建立自动释放池:
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
[pool addobject:c1];
[pool add object:c2];
[pool drain];//或[pool release]
3、autorelease方法不会改变对象的引用计数器,只是将对象放到自动释放池中。就是说对象每调用一次autorelease方法,在出自动释放池时就会统一调用一次对象的release方法。调用了autorelease方法并不会立即释放,也不会改变对象的计数器
4、自动释放池按照栈的顺序(后进先出,就是说越是最后调用autorelease的对象在出自动释放池统一release时就越先被调用)。
5、自动释放池的实质就是当自动释放池销毁后调用对象的release方法,不一定就能销毁对象(例如,如果一个对象因为retain的某种原因导致它的引用计数器的值大于1,则此时就无法销毁)
6、如果在OC的静态或非静态方法中声明并分配了一个对象,需要返回这个对象,一般在分配的同时调用autorelease方法,返回对象指针。或者在用alloc分配时不调用autorelease方法,返回指针的同时调用autorelease方法,即return
[对象指针 autorelease]; 就是说静态方法一般在内部调用autorelease方法,而不手动进行释放。
7、在iPhone/ipad等内存有限的手持设备上,并不建议使用autorelease方法;因为它是一种延迟释放。如果程序一直在运行,代码尚未出自动释放池之前,即使有很多对象不再需要了,但它们占用的内存并未完全释放。
8、由于自动释放池最后统一销毁对象,因此如果一个操作比较占内存(对象比较多或者对象占用内存比较多),最好不要放到自动释放池中或者放到多个自动释放池中。例如在for循环中生成对象并调用autorelease。
9、注意:自动释放池中只对调用autorelease方法的对象起延迟调用release的作用。对其他任何操作如release的调用没有任何的影响。
10、Cocoa内存管理的黄金定律:如果使用了alloc、[multable]copy、retain、new获得了一个对象,那么就必须调用一定次数的release或autorelease方法来激发dealloc析构函数的调用来释放对象的内存。
11、调用过多的autorelease会在池销毁的时候一一调用对象的release(autorelease调用的次数与alloc次数不符 如:alloc初始化3个对象,autorelease调了10次)过多就会造成二次删除的错误。如果一个对象调用的autorelease和release的总次数少于它内存计数器的值,也不会调用dealloc方法,这样会造成内存泄露。
12、autorelease的优点是:使用简单方便;缺点是:
(1)延迟释放的特点拉长了对象的声明周期,使不再使用的对象在释放池销毁之前仍然占用着内存.
(2)会减弱性能,因为自动释放池所做的工作要比直接使用release多很多。
验证代码如下:
当上面@autoreleaespool代码块执行完之后,三个对象都得到了释放,但是person4并没有释放,原因很简单,由于我们手动retain了一次,当自动释放池释放后调用四个对的release方法,当调用完person4的release之后它的引用计数器为1,所有它并没有释放(这是一个反例,会造成内存泄露);autorelase方法将一个对象的内存释放延迟到了自动释放池销毁的时候,因此上面person1,调用完autorelase之后它还存在,因此给name赋值不会有任何问题;在ObjC中通常如果一个静态方法返回一个对象本身的话,在静态方法中我们需要调用autorelease方法,因为按照内存释放原则,在外部使用时不会进行alloc操作也就不需要再调用release或者autorelase,所以这个操作需要放到静态方法内部完成。
1.//不要把大量循环操作放到同一个NSAutoreleasePool之间,道理同上,这样会使池中有大量对象,导致程序在运行时占用较多内存。比如下面这段代码:
int main (int argc, const charchar * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int i;
for (i=0;i<10000;i++){
Sample *s = [Sample new];
s.flag = i;
NSLog(@"%@",[s toString]);
[s autorelease];
}
[pool release];
return 0;
}
上面的代码运行时,必须等整个循环结束后才开始销毁对象。可以改进为下面这样:
int main (int argc, const charchar * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int i;
for (i=0;i<10000;i++){
Sample *s = [Sample new];
s.flag = i;
NSLog(@"%@",[s toString]);
[s autorelease];
if (i % 100==0)
{
[pool release];
pool = [[NSAutoreleasePool alloc] init];
}
}
[pool release];
return 0;
}
可以看出每生成100个对象便销毁池,再生成新的空池。避免了大量占用内存的情况
(此文转载 非原创)
1、新版的自动内存释放使用@autoreleasepool关键字声明一个代码块,如果一个对象在初始化时调用了autorelease方法,那么当代码块执行完之后在块中调用autorelease方法的对象都会自动调用一次release方法。这样一来就起到了自动释放的作用,同时对象的销毁过程也得到了延迟(统一调用release方法)
2、也有别的版本使用如下格式建立自动释放池:
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
[pool addobject:c1];
[pool add object:c2];
[pool drain];//或[pool release]
3、autorelease方法不会改变对象的引用计数器,只是将对象放到自动释放池中。就是说对象每调用一次autorelease方法,在出自动释放池时就会统一调用一次对象的release方法。调用了autorelease方法并不会立即释放,也不会改变对象的计数器
4、自动释放池按照栈的顺序(后进先出,就是说越是最后调用autorelease的对象在出自动释放池统一release时就越先被调用)。
5、自动释放池的实质就是当自动释放池销毁后调用对象的release方法,不一定就能销毁对象(例如,如果一个对象因为retain的某种原因导致它的引用计数器的值大于1,则此时就无法销毁)
6、如果在OC的静态或非静态方法中声明并分配了一个对象,需要返回这个对象,一般在分配的同时调用autorelease方法,返回对象指针。或者在用alloc分配时不调用autorelease方法,返回指针的同时调用autorelease方法,即return
[对象指针 autorelease]; 就是说静态方法一般在内部调用autorelease方法,而不手动进行释放。
7、在iPhone/ipad等内存有限的手持设备上,并不建议使用autorelease方法;因为它是一种延迟释放。如果程序一直在运行,代码尚未出自动释放池之前,即使有很多对象不再需要了,但它们占用的内存并未完全释放。
8、由于自动释放池最后统一销毁对象,因此如果一个操作比较占内存(对象比较多或者对象占用内存比较多),最好不要放到自动释放池中或者放到多个自动释放池中。例如在for循环中生成对象并调用autorelease。
9、注意:自动释放池中只对调用autorelease方法的对象起延迟调用release的作用。对其他任何操作如release的调用没有任何的影响。
10、Cocoa内存管理的黄金定律:如果使用了alloc、[multable]copy、retain、new获得了一个对象,那么就必须调用一定次数的release或autorelease方法来激发dealloc析构函数的调用来释放对象的内存。
11、调用过多的autorelease会在池销毁的时候一一调用对象的release(autorelease调用的次数与alloc次数不符 如:alloc初始化3个对象,autorelease调了10次)过多就会造成二次删除的错误。如果一个对象调用的autorelease和release的总次数少于它内存计数器的值,也不会调用dealloc方法,这样会造成内存泄露。
12、autorelease的优点是:使用简单方便;缺点是:
(1)延迟释放的特点拉长了对象的声明周期,使不再使用的对象在释放池销毁之前仍然占用着内存.
(2)会减弱性能,因为自动释放池所做的工作要比直接使用release多很多。
验证代码如下:
当上面@autoreleaespool代码块执行完之后,三个对象都得到了释放,但是person4并没有释放,原因很简单,由于我们手动retain了一次,当自动释放池释放后调用四个对的release方法,当调用完person4的release之后它的引用计数器为1,所有它并没有释放(这是一个反例,会造成内存泄露);autorelase方法将一个对象的内存释放延迟到了自动释放池销毁的时候,因此上面person1,调用完autorelase之后它还存在,因此给name赋值不会有任何问题;在ObjC中通常如果一个静态方法返回一个对象本身的话,在静态方法中我们需要调用autorelease方法,因为按照内存释放原则,在外部使用时不会进行alloc操作也就不需要再调用release或者autorelase,所以这个操作需要放到静态方法内部完成。
1.//不要把大量循环操作放到同一个NSAutoreleasePool之间,道理同上,这样会使池中有大量对象,导致程序在运行时占用较多内存。比如下面这段代码:
int main (int argc, const charchar * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int i;
for (i=0;i<10000;i++){
Sample *s = [Sample new];
s.flag = i;
NSLog(@"%@",[s toString]);
[s autorelease];
}
[pool release];
return 0;
}
上面的代码运行时,必须等整个循环结束后才开始销毁对象。可以改进为下面这样:
int main (int argc, const charchar * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int i;
for (i=0;i<10000;i++){
Sample *s = [Sample new];
s.flag = i;
NSLog(@"%@",[s toString]);
[s autorelease];
if (i % 100==0)
{
[pool release];
pool = [[NSAutoreleasePool alloc] init];
}
}
[pool release];
return 0;
}
可以看出每生成100个对象便销毁池,再生成新的空池。避免了大量占用内存的情况
(此文转载 非原创)
相关文章推荐
- [UVA 11526]H(n)[数学]
- 静态变量和静态方法的访问权限
- 面向对象
- MySQL与Oracle的语法区别详细对比
- JAVA多线程
- Shuffle'm Up(POJ--3087
- HDU 5336 XYZ and Drops (BFS模拟)
- cocos2d-x开发日志04 ——计划任务
- 如何挑选老师
- 视图、存储过程
- iOS开发核心语言Objective C语言 —— 特有语法及设计模式
- 输入n,分别用*输出边长为n的实心菱形和空心菱形。
- 设计模式--浅谈
- HDU 1213 How Many Tables
- MFC+Direct2D简化坐标平移缩放
- Oracle数据库表被锁
- JavaScript基础学习之-JavaScript权威指南--3.2文本
- 刀哥多线程同步任务作用gcd-07-sync_task
- 去哪网实习总结:开发定时任务(JavaWeb)
- Highways