OC中自动释放池原理深入剖析
2016-07-28 17:00
295 查看
一、对象------>release(retain -1)----------->(当retain count=0时)dealloc方法调用-------->销毁
说明:
1、销毁对象时肯定先走release方法,如果之后retain count还大于1,则不会释放如果retain count=0,则自动执行dealloc方法,进行销毁
2、执行alloc 方法和copy方法,retain count才会加1.
3、指针赋值时,retain count 不会+1,要想+1,手动调用retain
二、当创建一个对象时,有四种方式 alloc,new,copy, mutablecopy,
用完了以后需要手动调用release才行。那么有没有不需要手 动调用的。答案:autorelease
在创建对象的时候这样做
[[[classA alloc] init] autorelease] 这样建立的对象,就具备autorelase能力, 后面就不需要再调用release了。那为什么?
iphone项目启动后,xcode会帮你建立自动释放池auto release pool ,这个自动释放池中会建立一个数组,存放那些具备autorelease能力的对象。
只有当程序退出时或手动调用pool release时,自动释放池会释放其中所有autorlease能力的对象,让retain count全部减1,如果此时还大于1则不会调用alloc释放对象。
注意事项;
1、autorelease不便大量使用,因为容易造成内存不足。
2、[NSString stringwithFormat:@"123"]这样创建的对象是具备autorelease能力的,所以自动释放池释放的时候,会让retain count-1,然后看一下是不是等于0,决定是否调用alloc方法看是否可以回收。
如果你想让他当全局变量,不想让其回收的话,那么你可以手动调用一下retain,然后最终,你自己决定再release
练习 :
for (int i = 0 ; i < largeNumber; i++) {
NSString *str = [NSString stringWithFormat:@"hello -%04d",i];
}
这个题,str对象能否释放。
分析:
以上是一个消息循环, 所以此时会自动创建一个runloop释放池,然后具备autorelease能力的str对象是存到这里的。只有当循环结束的时候,释放池才会释放所有autolease对象。
所以无法做到循环一次就释放一次。如果让每一次的循环结束时都释放一次内存,怎么做呢?
答案是:创建局部自动释放池。
for (int i = 0 ; i < largeNumber; i++) {
@autoreleasepool {
NSString *str = [[NSString alloc]initWithFormat:@"hello -%04d",i];
}
}
总结:做多线程开发时,需要在线程调度方法中手动添加自动释放池,尤其是当执行循环的时候,如果循环内部有使用类的快速创建方法创建的对象, 一定要将循环体放到自动释放池中。
说明:
1、销毁对象时肯定先走release方法,如果之后retain count还大于1,则不会释放如果retain count=0,则自动执行dealloc方法,进行销毁
2、执行alloc 方法和copy方法,retain count才会加1.
3、指针赋值时,retain count 不会+1,要想+1,手动调用retain
二、当创建一个对象时,有四种方式 alloc,new,copy, mutablecopy,
用完了以后需要手动调用release才行。那么有没有不需要手 动调用的。答案:autorelease
在创建对象的时候这样做
[[[classA alloc] init] autorelease] 这样建立的对象,就具备autorelase能力, 后面就不需要再调用release了。那为什么?
iphone项目启动后,xcode会帮你建立自动释放池auto release pool ,这个自动释放池中会建立一个数组,存放那些具备autorelease能力的对象。
只有当程序退出时或手动调用pool release时,自动释放池会释放其中所有autorlease能力的对象,让retain count全部减1,如果此时还大于1则不会调用alloc释放对象。
注意事项;
1、autorelease不便大量使用,因为容易造成内存不足。
2、[NSString stringwithFormat:@"123"]这样创建的对象是具备autorelease能力的,所以自动释放池释放的时候,会让retain count-1,然后看一下是不是等于0,决定是否调用alloc方法看是否可以回收。
如果你想让他当全局变量,不想让其回收的话,那么你可以手动调用一下retain,然后最终,你自己决定再release
练习 :
for (int i = 0 ; i < largeNumber; i++) {
NSString *str = [NSString stringWithFormat:@"hello -%04d",i];
}
这个题,str对象能否释放。
分析:
以上是一个消息循环, 所以此时会自动创建一个runloop释放池,然后具备autorelease能力的str对象是存到这里的。只有当循环结束的时候,释放池才会释放所有autolease对象。
所以无法做到循环一次就释放一次。如果让每一次的循环结束时都释放一次内存,怎么做呢?
答案是:创建局部自动释放池。
for (int i = 0 ; i < largeNumber; i++) {
@autoreleasepool {
NSString *str = [[NSString alloc]initWithFormat:@"hello -%04d",i];
}
}
总结:做多线程开发时,需要在线程调度方法中手动添加自动释放池,尤其是当执行循环的时候,如果循环内部有使用类的快速创建方法创建的对象, 一定要将循环体放到自动释放池中。
相关文章推荐
- AngularJS 中文API参考手册
- 这是关于RadioButton一个坑爹的问题,请让我自杀好吗!
- HBase-1.2.1之查找Region位置的源码学习
- QT中的setGeometry参数
- Eclipse FindBugs插件安装与使用
- 视频会议亮点剖析
- 仿IOS 带字母索引的滑轮控件
- 搭建SSH框架时遇到的问题及解决方法
- jfinal2.2 + druid + oracle 11g ORA-00911: 无效字符
- 设计模式GOF23——单例模式
- jenkins和docker 使用docker作为slave
- 数据挖掘——各种分类算法的优缺点
- GDT(全居描述符表)和LDT(局部描述符表)
- 观止云技术实践| 可追溯日志:视频云时代的新运维大胸器
- 深入理解ThreadLocal
- HDU 1044 Collect More Jewels【BFS+DFS+建立距离图】
- STM32F4采集核心板调试记录
- 牛客网 7-28 网络基础 操作系统 编译与体系结构 30题知识点总结
- 用virtual environment让库管理变得简单
- UITextField 只允许输入数字和字母 解决联想中文等问题