NSRunloop的解析及autorelease的释放时机
来源:互联网 发布:sql基本语句大全 编辑:程序博客网 时间:2024/06/04 22:37
http://blog.csdn.net/xinruiios/article/details/8929915
iOS的运行时是由一个一个runloop组成的,每个runloop都会执行下图所示的一些步骤:
每个runloop中都创建一个Autorelease Pool,并在runloop的末尾进行释放,
所以,一般情况下,每个接受autorelease消息的对象,都会在下个runloop开始前被释放。也就是说,在一段同步的代码中执行过程中,生成的对象接受autorelease消息后,一般是不会在代码段执行完成前释放的。
当然也有让autorelease提前生效的办法:自己创建Pool并进行释放
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSArray * array = [[[NSArray alloc] init] autorelease];
[pool drain];
上面的array就会在[pool drain]执行时被释放。
所以对于你遇到的问题,可以在for循环外嵌套一个Autorelease Pool进行管理,例如
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
for (int i = 0; i < 10000; i++)
{
// ...
}
[pool drain];
但由于你提到了生成的每个实例可能会比较大。只在循环外嵌套,可能导致在pool释放前,内存里已经有10000个实例存在,造成瞬间占用内存过大的情况。
因此,如果你的每个实例仅需要在单次循环过程中用到,那么可以考虑可以在循环内创建pool并释放
for (int i = 0; i < 10000; i++)
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// ...
[pool drain];
}
线程中没有source的runloop会自动结束。
事件由NSRunLoop 类处理。RunLoop监视操作系统的输入源,如果没有事件数据,不消耗任何CPU 资源。如果有事件数据,run loop 就发送消息,通知各个对象。
用 currentRunLoop 获得 runloop的 reference,给 runloop 发送run 消息启动它。
下面介绍四种情况是使用runloop的场合:
1.使用端口或自定义输入源和其他线程通信
2.子线程中使用了定时器
3.cocoa中使用任何performSelector到了线程中运行方法
4.使线程履行周期性任务,(我把这个理解与2相同)
如果我们在子线程中用了NSURLConnection异步请求,那也需要用到runloop,不然线程退出了,相应的delegate方法就不能触发。
这里通过小示例简单介绍以下有关runloop方面的问题:
1.首先简单运行执行runlooprun函数并不会让系统停住等待事件,而是需要在运行runloop之前添加source,只有在有source的情况下线程才会停下来监听各种事件。
2.runloop的使用:
1)生成一个runloop source
// add send source
CFRunLoopSourceContext src_context ;
NSError * emsg = nil ;
// init send source context
src_context.version = 0;
src_context.info = inst;
src_context.retain = NULL;
src_context.release = NULL;
src_context.copyDescription = NULL;
src_context.equal = NULL;
src_context.hash = NULL;
src_context.schedule = NULL;
src_context.cancel = NULL;
src_context.perform = &callback ;//设置唤醒是调用的回调函数
// create send source from context
CFRunLoopSourceRef runloopSource ;
runloopSource = CFRunLoopSourceCreate (NULL, 0, &src_context) ;
2)将source加入线程所属的runloop中
// add the send source into run loop
CFRunLoopRef threadRunLoop ;
threadRunLoop = CFRunLoopGetCurrent() ;
CFRunLoopAddSource (threadRunLoop ,
runloopSource,
kCFRunLoopDefaultMode);
3)运行runloop
CFRunLoopRun() ;
4)如何调用runloop(首先可以将各个线程的runloop和source保存起来)
CFRunLoopSourceSignal(runloopSource) ;// 参数是你调用的runloop的source
CFRunLoopWakeUp(threadRunLoop) ;//这句话的作用时立即执行该runloop的事件,如果没有这句话系统会在空闲的时候执行刚才的runloopSource相关的事件
3.如何停掉runloop退出线程
CFRunLoopStop(threadRunLoop) ;这个函数可以停掉runloop是线程正常退出
4.ios整个系统基本上是基于runloop这种架构的,ios程序的main线程整体上也是基于runloop的,各种事件的响应应该也是基于source这种思路。
- NSRunloop的解析及autorelease的释放时机
- NSRunloop的解析及autorelease的释放时机
- NSRunloop的解析及autorelease的释放时机
- autorelease的对象的释放时机
- 75. Autorelease机制及释放时机
- 探索子线程autorelease对象的释放时机
- autorelease对象的释放
- 回顾自动释放池的使用及个人理解autorelease
- Autorelease自动释放池的使用
- autorelease pool的内存管理之-自动释放池
- Use autorelease to Send a Deferred release---使用autorelease发送一个延期释放的消息
- if代码块中定义的变量的释放时机
- NSRunLoop中Autorelease pool 管理
- objective-C 的内存管理之-自动释放池(autorelease pool)
- objective-C 的内存管理之-自动释放池(autorelease pool)
- objective-C 的内存管理之-自动释放池(autorelease pool)
- objective-C 的内存管理之-自动释放池(autorelease pool)
- objective-C 的内存管理之-自动释放池(autorelease pool)
- oracle相关的linux系统内核参数详解(不断补充中)
- Objective-C学习笔记-之操作文件
- 图的建立(邻接矩阵)+深度优先遍历+广度优先遍历+Prim算法构造最小生成树(Java语言描述)
- 图像物体分类和物体检测算法的概括
- grub rescue
- NSRunloop的解析及autorelease的释放时机
- JAVA程序设计(14.2)----- 图书馆管理系统 初步设计 界面篇
- XMPP服务器环境的搭建
- boost库中bind()和function()的使用方法
- Oracle数据库mybatis 插入空值时报错(with JdbcType OTHER)
- tomcat配置HTTPS
- php用户登录以及后台处理
- HTML 入门,30分钟入门教程.
- 数据库集群实施