文档章节

NSRunloop的解析及autorelease的释放时机

刀客445
 刀客445
发布于 2016/05/19 17:17
字数 943
阅读 87
收藏 0
点赞 2
评论 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
博文 36
码字总数 10222
作品 0
杭州
NSRunloop,runloop,autoReleasePool和thread的关系理解及案例解决

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

北方人在上海 ⋅ 2016/05/23 ⋅ 0

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

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

长平狐 ⋅ 2012/10/25 ⋅ 0

iPhone/Mac Objective-C内存管理教程和原理剖析(四)系统自动创建新的aut...

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

Liuxz-aaa ⋅ 2011/06/08 ⋅ 0

oc内存管理《4》

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

去开原 ⋅ 2014/02/09 ⋅ 0

iPhone/Mac Objective-C内存管理教程和原理剖析

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

黑衣李白 ⋅ 2012/12/27 ⋅ 0

对Objective-C内存管理策略的理解

Objective-C的内存管理策略是基于“拥有关系”的。凡是被“拥有”的对象,不会被回收。对内存的管理,实际上就是对“拥有”关系的管理。 通过开头名称为”alloc”,”new”,”copy”,”mutab...

nswish ⋅ 2014/08/06 ⋅ 0

iPhone开发之NSRunLoop的进一步理解

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

andyhe91 ⋅ 2014/04/14 ⋅ 1

【Runloop】深入理解原理和机制

用runloop解决cpu空转 runloop运行模式 了解设置模式 runloop在哪里 使用方法 换起runloop的三种方式 额外了解

创意总监 ⋅ 2016/06/01 ⋅ 0

iOS 内存管理基础知识

内存管理问题,首先要知道一个概念,引用计数。Objective-C 的内存管理基于引用计数(Reference Count)。如果要使用一个对象,并希望确保在使用期间对象不被释放,需要保证在使用过程中引用...

广州英趣科技 ⋅ 2013/06/19 ⋅ 0

Objective-C高级编程之内存管理篇

iOS的内存管理是采用引用计数的方式,引用计数分为手动引用计数和自动引用计数(ARC)。前者要求开发者手动管理内存,自己负责内存的申请与释放,后者是苹果推出的自动管理内存的方式,但其实...

凝望向北 ⋅ 2017/02/24 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Linux kernel脉络和主干总结

写在前面 前人常说,对Linux操作系统/内核的理解,是计算机行业从业者的内功,决定了你在技术领域想走多远。但内核的庞大以及学习曲线之陡峭,总让我在学习途中觉得犹如“管中窥豹”。 随着工...

Markz0928 ⋅ 26分钟前 ⋅ 0

在gcc中使用intel风格的内联汇编

很简单,内联汇编使用asm(“.intel_syntax noprefix/n”)声明一下,以后的内联汇编就可以用intel风格了,构建可执行文件时给gcc加上-masm=intel参数。 先写一个小程序测试一下: [cpp] view...

simpower ⋅ 36分钟前 ⋅ 0

NIO 之 ByteBuffer实现原理

相关文章 BIO、NIO、AIO 内部原理分析 NIO 之 Selector实现原理 NIO 之 Channel实现原理 前言 Java NIO 主要由下面3部分组成: Buffer Channel Selector 在传统IO中,流是基于字节的方式进行...

轨迹_ ⋅ 45分钟前 ⋅ 0

Jenkins docker权限问题

环境Ubuntu Server 工具 jenkins-war:2.89.2 报错信息 Cannot connect to the Docker daemon. Is the docker daemon running on this host?Build step 'Execute shell' marked build as fai......

Pulsar-V ⋅ 46分钟前 ⋅ 0

180621-一个简单的时间窗口设计与实现

如何设计一个计数的时间窗口 时间窗口,通常对于一些实时信息展示中用得比较多,比如维持一个五分钟的交易明细时间窗口,就需要记录当前时间,到五分钟之前的所有交易明细,而五分钟之前的数...

小灰灰Blog ⋅ 今天 ⋅ 0

Android之Dalvik、ART、JIT、AOT

Android之Dalvik、ART、JIT、AOT 本文内容:Dalvik、ART、JIT、AOT之间关系 本文定位:知识记录 学习过程记录,加深理解,提升文字组合表达能力。也希望能给学习的同学一些灵感 本文整理于[...

lichuangnk ⋅ 今天 ⋅ 0

Thrift RPC实战(五) thrift连接池

Thrift本身没有提供连接池,我们可以用Apache Commons Pool2来实现一个 一、定义对象工厂 BasePooledObjectFactory<T> extends BaseObject implements PooledObjectFactory<T> public class......

lemonLove ⋅ 今天 ⋅ 0

git 命令简写

简写 命令 g git gst git status gd git diff gdc git diff --cached gdv git diff -w "$@" | view - gl git pull gup git pull --rebase gp git push gc git commit -v gc! git commit -v ......

charley158 ⋅ 今天 ⋅ 0

Java中的锁使用与实现

1.Lock接口 锁是用来控制多个线程访问共享资源的方式,一般来说,一个锁能够防止多个线程同时访问共享资源。 在Lock出现之前,java程序是靠synchronized关键字实现锁功能的,而Java SE5之后,...

ZH-JSON ⋅ 今天 ⋅ 0

Intellij IDEA神器常用技巧四-类和方法注释模板设置

IDEA自带的注释模板不是太好用,我本人到网上搜集了很多资料系统的整理了一下制作了一份比较完整的模板来分享给大家,我不是专业玩博客的,写这篇文章只是为了让大家省事。 这里设置的注释模...

Mkeeper ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部