文档章节

NSRunloop的解析及autorelease的释放时机

刀客445
 刀客445
发布于 2016/05/19 17:17
字数 943
阅读 98
收藏 0

 

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];

}


 

对于多线程来说,每一个线程都有自己的runloop, 主线程是默认开启的,创建的子线程要手动开启,因为NSApplication只启动main applicaiton thread

线程中没有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这种思路。

本文转载自:http://blog.csdn.net/xinruiios/article/details/8929915

共有 人打赏支持
刀客445
粉丝 2
博文 47
码字总数 10222
作品 0
杭州
NSRunloop,runloop,autoReleasePool和thread的关系理解及案例解决

1.NSRunloop NSRunloop顾名思义,就是一个消息循环,它会侦测输入源(input source)和定时源(timer source),然后做回调处理。这和windows的消息处理非常类似,只不过你无法看到类似SendMessa...

北方人在上海
2016/05/23
195
0
iPhone/Mac Objective-C内存管理教程和原理剖析(四)系统自动创建新的aut...

四 系统自动创建新的autorelease pool 在生成新的Run Loop的时候,系统会自动创建新的autorelease pool(非常感谢网友hhyytt和neogui的提醒)。注意,此处不同于xcode在新建项目时自动生成的...

Liuxz-aaa
2011/06/08
0
0
iPhone/Mac Objective-C内存管理教程和原理剖析 【四、系统自动创建新的autorelease pool】

四 系统自动创建新的autorelease pool 在生成新的Run Loop的时候,系统会自动创建新的autorelease pool(非常感谢网友hhyytt和neogui的提醒)。注意,此处不同于xcode在新建项目时自动生成的...

长平狐
2012/10/25
36
0
iPhone/Mac Objective-C内存管理教程和原理剖析

版权声明 此文版权归作者Vince Yuan (vince.yuan#gmail.com)所有。欢迎非营利性转载,转载时必须包含原始链接http://vinceyuan.cnblogs.com/,且必须包含此版权声明的完整内容。 版本 1.1 发...

黑衣李白
2012/12/27
0
0
iPhone开发之NSRunLoop的进一步理解

iPhone应用开发中关于NSRunLoop的概述是本文要介绍的内容,NSRunLoop是一种更加高明的消息处理模式,他就高明在对消息处理过程进行了更好的抽象和封装,这样才能是的你不用处理一些很琐碎很低...

andyhe91
2014/04/14
0
1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

文件的压缩与解压(linux)

Linux下*.tar.gz文件解压缩命令 1.压缩命令:   命令格式:tar -zcvf 压缩后文件名.tar.gz 被压缩文件名 可先切换到当前目录下。压缩文件名和被压缩文件名都可加入路径。 2.解压缩命令: ...

qimh
21分钟前
1
0
invalid character found in the request target 异常

这个异常时因为Tomcat 9不支持请求格式出现“{”等非法字符的问题 因为tomcat版本问题遇到的坑,记录一下。 问题 今天由于要测试一下订单详情页的异步查询,在本地起了一个服务,发送的请求是...

edwardGe
25分钟前
1
0
发现抓包软件fiddler的bug

1个请求他跳转之后,直接400,被拦在了Apache,使用fiddler 的,replay requests 是同样的结果,但是replay composer确是正常的。 也就是说这replay requests 是发原来的包,replay composer...

NLGBZJ
36分钟前
1
0
linux screen 命令详解

shell关闭后, 主机仍然运行 screen命令 启动jenkins以后, screen, 然后按ctrl+a 再按d 这样暂停了子界面, 这时候回到了父界面 用screen –ls查看目前子界面的状态 [root@free /]# screen -l...

SuShine
36分钟前
1
0
mac机器切换无线网络导致网页不能打开的问题

问题: 公司和家里使用不同的WI-FI,每次从家到公司时自动切换网络后,公司的许多地址不能访问, ping域名是可以ping同的,但是网页却打不开... 问题分析: 初步猜想是DNS缓存的问题? 对于MAC系统没...

Lennie002
39分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部