一:常驻线程 :当需要一个线程一直处理一些耗时操作时,可以让它拥有一个RunLoop。具体代码如下:

   1.通过给RunloopMode里加源来保证RunLoop不直接退出。

这里有个很重要得知识点,runloop对象如果mode为空得话,会直接返回。在下面这段代码中的run方法里:

    [[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];  // 给RunLoop的Mode里添加内容

    [[NSRunLoop currentRunLoop] run];// 开启RunLoop,默认是出于Default模式。

保证RunLoop对象的mode不会为空,也就是不会直接退出,保证线程持续运行。

@interface ViewController ()
@property (nonatomic, strong) ZZThread *testThread; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; // 创建自己的线程,并让其执行run方法
ZZThread *thread = [[ZZThread alloc] initWithTarget:self selector:@selector(run) object:nil];
self.testThread = thread;
[self.testThread start]; }
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self performSelector:@selector(test) onThread:self.testThread withObject:nil waitUntilDone:NO ];
}
- (void)test{
NSLog(@"%s ------- %@",__func__,[NSThread currentThread]);
}
// 给线程添加一个RunLoop 让线程"Live"
- (void)run
{
NSLog(@"%s -------------- %@",__func__,[NSThread currentThread]); // 如果RunLoop的Mode内没有内容,RunLoop会被直接销毁
[[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode]; // 给RunLoop的Mode里添加内容 [[NSRunLoop currentRunLoop] run];// 开启RunLoop,默认是出于Default模式。 NSLog(@"-------------run end -----------");// 正面run方法一直没有结束 } @end

2.给Runloop中添加定时器也可以保证RunLoop直接退出。

- (void)viewDidLoad {
[super viewDidLoad]; // 创建自己的线程,并让其执行run方法
ZZThread *thread = [[ZZThread alloc] initWithTarget:self selector:@selector(test2) object:nil];
self.testThread = thread;
[self.testThread start]; } - (void)test2{ NSTimer *timer = [NSTimer timerWithTimeInterval: target:self selector:@selector(test) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode ]; [[NSRunLoop currentRunLoop] run]; }
- (void)test{
NSLog(@"%s ------- %@",__func__,[NSThread currentThread]);
}

二:自动释放池

1.RunLoop的自动释放池的生命周期

RunLoop在开始步骤1时会创建自动释放池,并将之后的需要创建的临时对象都放在池子里,然后在步骤6的时候会将池子销毁,也就是对所有对象做一次realease操作。

也就是说RunLoop每跑一圈,到休眠这个周期里,自动释放池的生命周期同时也是从创建到销毁。

  2016-1-24补充:

    Runloop内部是通过注册一个Observer监听RunLoop的状态,当监听到RunLoop的状态为before waiting时,就会释放自动释放池。(kCFRunLoopBeforeWaiting) 

    需要注意的是,Observer也会在这个时候在执行完销毁自动释放池的操作后,再创建一个自动释放池,而不是在步骤1。 

   也就是说RunLoop中的自动释放池都是在步骤6中销毁与创建的!!!

  2016 - 1- 24 16:00再次补充:

   可以打印出Runloop对象,发现它内部监听自动释放池的obserer对象的activities的值为1和160(32 + 128)

   也就是说observer对象其实监听了Runloop的三个状态:kCFRunLoopEntry,kCFRunLoopBeforeWaiting,kCFRunLoopExit

   kCFRunLoopEntry:Runloop的进入状态,此时会第一次创建自动释放池

   kCGRunLoopBeforeWaiting: RunLoop的休眠状态前,此时会销毁第一次在进入时创建的自动释放池并又创建一个新的自动释放池。

   kCFRunLoopExit: 直接销毁自动释放池

 

2.所以在创建RunLoop对象时应该也用一个自动释放池包住

// 给线程添加一个RunLoop 让线程"Live"
- (void)run
{
@autoreleasepool { NSLog(@"%s -------------- %@",__func__,[NSThread currentThread]); // 如果RunLoop的Mode内没有内容,RunLoop会被直接销毁
[[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode]; // 给RunLoop的Mode里添加内容 [[NSRunLoop currentRunLoop] run];// 开启RunLoop,默认是出于Default模式。 NSLog(@"-------------run end -----------");// 正面run方法一直没有结束 } }

2016 - 1- 21 - RunLoop使用(2016-1-24修改一次)&(2016 - 1 - 24 再次修改)的更多相关文章

  1. FFMpeg ver 20160219-git-98a0053 滤镜中英文对照 2016.02.21 by 1CM

    FFMpeg ver 20160219-git-98a0053 滤镜中英文对照 2016.02.21 by 1CM T.. = Timeline support 支持时间轴 .S. = Slice t ...

  2. ”耐撕“团队 2016.3.21 站立会议3 2 1 GO!

    ”耐撕“团队 2016.3.21 站立会议 时间:2016.3.21  ① 17:20-17:45  ②17:55-18:10  总计40分钟 成员: Z 郑蕊 * 组长 (博客:http://www ...

  3. Technical Committee Weekly Meeting 2016.06.21

    Meeting time: 2016.June.21 1:00~2:00 Chairperson:  Thierry Carrez Meeting summary: 1.Add current hou ...

  4. Murano Weekly Meeting 2016.06.21

    Meeting time: 2016.June.21 1:00~2:00 Chairperson:  Kirill Zaitsev, from Mirantis Meeting summary: 1. ...

  5. CHAPTER 24 History of Our Planet 第24章 我们行星的历史

    CHAPTER 24 History of Our Planet 第24章 我们行星的历史 Uncovering the bones of ancient beasts is only part of ...

  6. OneZero第一次站立会议&Sprint Planning Meeting(2016.3.21)

    会议时间:2016年3月21日 11:40~12:00 会议成员:冉华,张敏,王巍,夏一鸣. 会议目的:列举第一周工作内容,确定第一周工作分配.即挑选出一个Story作为本次迭代完成的目标. 会议内容 ...

  7. 2016 - 1 - 20 runloop学习(2)

    一:CFRunLoopModeRef 1. CFRunLoopModeRef带表RunLoop的运行模式 2. 一个Runloop可以有若干个mode,每个mode又包含若干个sourse,timer ...

  8. 2016 - 1 - 20 runloop学习

    一:Runloop基本知识 1.本质就是运行循环 2.基本作用: 2.1保证程序持续运行 2.2处理APP中的各种事件:触摸,定时器,selector... 2.3节省CPU资源,系统程序性能:它会让 ...

  9. 2016/12/21 dplの课练

    1.将/etc/passwd第行的最后一段全部改成/bin/bash cat 1 |sed -n '1,$p' |egrep '.*:' -o |sed 's/$/\bin\/bash/' 2.将/e ...

随机推荐

  1. 静态类和静态类成员(C# 编程指南)

    静态类与非静态类基本相同,但存在一个区别:静态类不能实例化. 也就是说,不能使用 new 关键字创建静态类类型的变量. 因为没有实例变量,所以要使用类名本身访问静态类的成员. 例如,如果名为 Util ...

  2. 一些简单css3效果的整理

    代码: html: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  3. 1029c语言文法2理解

    program → external_declaration | program external_declaration <程序>→ <外部声明>|<程序>< ...

  4. C# System.Diagnostics.Stopwatch 类

    测量一个时间间隔的运行时间 a.调用 Start 方法 b.调用 Stop 方法 c.使用 Elapsed 属性检查运行时间. 如: System.Diagnostics.Stopwatch stop ...

  5. python中cPickle的用法

    import cPickle as p f = file('data.txt' , 'w') data = (1 , 'A' , "hello") p.dump(data , f) ...

  6. 意外的节点类型 Element。只能在简单内容或空内容上调用 ReadElementString 方法

    问题出现的情景: 在调用携程团购接口时,需要把获取的xml字符串反序列化实体对象,出现了这个错误. 详情: 在对xml文档有这样一条语句“ <Description Category=" ...

  7. enum使用总结

    enum的一般使用方法是它会占用最大的成员长度 然后我忘记的是enum还可以这样使用 enum ExctState { START, SUCCEED, FAILURE=6, REJECT, }; 这样 ...

  8. 转载 网页打印时设置A4大小

    最近开发项目时遇到了网页打印的问题,这是问题之二,打印宽度设置 在公制长度单位与屏幕分辨率进行换算时,必须用到一个DPI(Dot Per Inch)指标. 经过我仔细的测试,发现了网页打印中,默认采用 ...

  9. extjs DateField 的值用getValue()方法获取后是一大堆字符串,类似Tue Dec 07 2010 00:00:00 GMT 0800,这玩意存入数据库实在不好办。。。

    extjs DateField 的值用getValue()方法获取后是一大堆字符串,类似Tue Dec 07 2010 00:00:00 GMT 0800,这玩意存入数据库实在不好办...所以要把它格 ...

  10. 发送广播BroadcastReceiver

    import android.os.Bundle;import android.app.Activity;import android.content.Intent;import android.vi ...