说来,我忘东西还真是飞快。
前一个月自认为把RunLoop研究得比较透彻了,但因为没有在项目中实际使用的缘故,到现在竟然都快忘了,我必须得把它记录下来,以后忘记了我还可以在这里找回来再看看。
下面是测试代码:
- (void)viewDidLoad
{
[super viewDidLoad];
//这里偷个懒,直接使用performSelectorInBackground来创建一个线程,并执行configRunLoop方法
[self performSelectorInBackground:@selector(configRunLoop) withObject:nil];
UIButton* __button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[__button1 setTitle:@"Fire Event" forState:UIControlStateNormal];
//触发事件启动RunLoop
[__button1 addTarget:self action:@selector(triggerEvent) forControlEvents:UIControlEventTouchUpInside];
__button1.frame = CGRectMake(0, 0, 100, 80);
[self.view addSubview:__button1];
UIButton* __button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[__button2 setTitle:@"Stop RunLoop" forState:UIControlStateNormal];
//RunLoop周期完成后自动退出线程
[__button2 addTarget:self action:@selector(stopRunloop) forControlEvents:UIControlEventTouchUpInside];
__button2.frame = CGRectMake(110, 0, 120, 80);
[self.view addSubview:__button2];
}
- (void)stopRunloop{
_shouldStop = YES;
}
- (void)triggerEvent{
if (CFRunLoopIsWaiting(_runLoopRef)) {
NSLog(@"RunLoop 正在等待事件输入");
//添加输入事件
CFRunLoopSourceSignal(_source);
//唤醒线程,线程唤醒后发现由事件需要处理,于是立即处理事件
CFRunLoopWakeUp(_runLoopRef);
}else {
NSLog(@"RunLoop 正在处理事件");
//添加输入事件,当前正在处理一个事件,当前事件处理完成后,立即处理当前新输入的事件
CFRunLoopSourceSignal(_source);
}
}
//此输入源需要处理的后台事件
static void fire(void* info __unused){
NSLog(@"我现在正在处理后台任务");
sleep(5);
}
- (void)configRunLoop{
//这里获取到的已经是某个子线程了哦,不是主线程哦
_tThread = [NSThread currentThread];
//这里也是这个子线程的RunLoop哦
_runLoopRef = CFRunLoopGetCurrent();
bzero(&_source_context, sizeof(_source_context));
//这里创建了一个基于事件的源
_source_context.perform = fire;
_source = CFRunLoopSourceCreate(NULL, 0, &_source_context);
//将源添加到当前RunLoop中去
CFRunLoopAddSource(_runLoopRef, _source, kCFRunLoopCommonModes);
while (!_shouldStop) {
NSLog(@"RunLoop 开始运行");
//每次RunLoop只运行10秒,每10秒做一次检测,如果没有需要处理的后台任务了,就让此线程自己终止,不用暴力Kill
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, NO);
NSLog(@"RunLoop 停止运行");
}
_tThread = nil;
}
这里是更详细的说明和解释
附件是Demo的完整代码
分享到:
相关推荐
CFRunLoop NSRunLoop 数据库 SQLite 网络 TCP UDP DNS解析 HTTP协议 NetworkExtension 网络安全 NSURLSession 证书 iOS基础 UI(控件) Controller(控制器) GestureRecognizer(手势) 布局 Frame AutoLayout ...
NSRunLoop是基于CFRunLoopRef的封装,不是线程安全 CFRunLoopRef的线程安全性:CFRunLoopRef不是在线程刚创建的时候创建的,而是在线程获取的时候创建的,如果不主动获取线程,一直不会有。CFRunLoopRef在创建时通过...
LightWeightRunLoop-A-Reactor-Style-NSRunLoop, NSRunLoop反应器样式实现 LightWeightRunLoop在其他线程,定时器,URLConnection,LWStream ( LWInputStream、LWOutputStream ),LWPort ( LWSocketPort ) 等上实现 ...
在网络访问时,一般都建议用异步访问,但是异步访问的话,需要传入delegate,并处理回调。不利于将所有的网络访问的方法集中到一个类中,所以我采用同步... 以使同步请求也可取消。while循环这段代码在旧版中是没有的。
RunLoop例子
runloop相关的代码整理。Timer,CustomSource,DispatchSource,ConfigRunLoop,ObserverRunloop等
在Thread的NSRunloop中添加进RunLoopSource也是在IOS里面获取常驻线程的一个主要方法手段(开源项目AFNetworking就是用这种手段获取的常驻线程)。从该演示代码我们还可以一窥Objective-C是怎样封装C以提供更加简单...
[[NSRunLoop currentRunLoop]addTimer:_timer forMode:NSDefaultRunLoopMode]; 改为: /*每秒刷新60次的定时器*/ _time = [CADisplayLink displayLinkWithTarget:self selector:@selector(play)]; /*将...
《NSThread 、NSRunLoop 和 Dispatch Queue》一文示例源代码
相对较多者)作者模块标题卖报的小画家SureMethod Swizzling开发实例汇总滕大鸟最实用的runtime总结黑花白花实际开发中的应用Run LoopsRun Loops 官方文档Run Loops 译文(第三章)CFRunLoop.c 源码CFRunLoop.h 源码...
、NSRunLoop 和 Dispatch Queue> 一文示例源代码
/** * In the event of an error, the socket is closed. * You may call "unreadData" during this call-back ...- (NSRunLoop *)onSocket:(AsyncSocket *)sock wantsRunLoopForNewSocket:(AsyncSocket *)newSocket;
如果你调用它接收连接,它将为每个连接启动新的实例,当然,也可以立即关闭这些连接 委托(delegate)支持。错误、连接、接收、完整的读取、完整的写入、进度以及断开连接,都可以通过委托模式调用 基于run loop的...
如果你调用它接收连接,它将为每个连接启动新的实例,当然,也可以立即关闭这些连接 委托(delegate)支持。错误、连接、接收、完整的读取、完整的写入、进度以及断开连接,都可以通过委托模式调用 基于run loop的,...
如果你调用它接收连接,它将为每个连接启动新的实例,当然,也可以立即关闭这些连接 委托(delegate)支持。错误、连接、接收、完整的读取、完整的写入、进度以及断开连接,都可以通过委托模式调用 基于run loop的...
> [[NSRunLoop currentRunLoop] addPort:mainPort > forMode:NSDefaultRunLoopMode]; > > NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; > [parameters setObject:mainPort forKey:@"port...
ConcurrentCource自己对NSRunLoop,NSOperation,GCD的一些心得,代码中都有注释
CZHCoundDownTime 公司的项目,求支持,... [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes]; } - (void)timerEvent { for (CZHCountDownModel *timeModel in self.timeArrays) {
iOS开发中,有两种常用的方法可以实现延迟执行,一种是使用GCD,另外一种是使用NSRunLoop类中提供的方法。 前言 对初学者来说,GCD似乎是一道迈不过去的坎,很多人在同步、异步、串行、并行和死锁这几个名词的漩涡中...