NSRunLoop (消息循环)
RunLoop就是消息循环,每一个线程内部都有一个消息循环。
只有主线程的消息循环默认开启,子线程的消息循环默认不开启。
NSRunLoop的作用
1,保证程序不退出
2.负责处理输入事件
3.如果没有事件发生.会让程序进入休眠状态
事件源 : input Sources 输入源
Timer Source 定时源
消息循环使用
1.创建输入源(定时源)
2.指定事件源再循环中运行的模式.并加入循环
//创建时间源
NSTimer *timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(task) userInfo:nil repeats:YES];
//定时源加到消息循环中去
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
循环的模式 (只有当消息模式 与循环的模式 匹配的时候,消息运行)
// NSDefaultRunLoopMode 默认模式下,拖动界面,计时器停止 最常用的循环模式
// NSRunLoopCommonModes 多模式的状态,拖动界面,不影响计时器工作 一组模式的集合
// 消息循环时模式
// kCFRunLoopDefaultMode 定时器工作的模式(默认模式)
// UITrackingRunLoopMode 拖动界面时的模式
1.创建消息
2.把消息放入循环,并指定消息运行的模式
3.在与循环的模式匹配的时候,消息运行
特点:子线程默认不开启消息循环,主线程默认开启消息循环。
子线程的 RunLoop默认是不开启的,而且不可以轻易开启,如果开启会形成死循环,然后不停地检测是否有事件发生,因此开启子线程的消息循环之后一定要关闭,防止程序挂掉,
子线程中的消息循环
//开启子线程的消息循环
//第一种方法 .无法停止
// [[NSRunLoop currentRunLoop] run];
//第二种方法 .制定循环运行时间,
[[NSRunLoop currentRunLoop]
runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]];
//第三种方式 推荐方式
//将shouldKeepRunning定义为全局的变量,并且设置为NO
// BOOL shouldKeepRunning = YES; // global
NSRunLoop *theRL = [NSRunLoop currentRunLoop];
NSLog(@"%d", shouldKeepRunning);
while (shouldKeepRunning &&
[theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
NSRunloop与autorelease pool
在主线程消息循环开始的时候创建自动释放池,在消息循环结束的时候,销毁释放池,
在循环过程中创建的临时对象,会自动添加到释放池中,在循环结束后会向池中所有对象发送 release 消息,释放所有 autorelease 对象,以减少内存消耗;
NSThread开启子线程的时候要自己创建自动释放池,否则会发生内存泄露