RunLoop-运行循环

2018-07-13  本文已影响0人  程序萌

runLoop

一个线程一次只能执行一个任务,执行完后线程退出。如果我们需要一个机制,让线程能随时处理事件但并不退出。

消耗很低,睡眠循环

循环监听事件(事件需要处理不主动发起通知,而是把自身状态变成待处理,runloop去循环监听待处理事件,发现后进行处理)

runloop底层实现推测是do_while,死循环

main函数里面用到runloop,保证app不退出,默认是开启的

线程保命:一个线程任务执行完就挂掉,只有任务执行不完,才会保命,这里用runloop对线程进行保命

和多线程结合使用
和JaveScript中的 Event loop相似

runloop死循环存在的目的:

runloop分类

主线程的runloop (主循环)
子线程的runloop (子循环)

runloop模式(五种)

runloop的应用

  //方式一
    NSTimer * timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timerModeth) userInfo:nil repeats:YES];
    NSRunLoop * mainRunLoop = [NSRunLoop currentRunLoop];
    [mainRunLoop addTimer:timer forMode:NSDefaultRunLoopMode];
    
    //方式二,可以直接触发,因为内部自动把timer加入到了runloop中,模式是默认模式NSDefaultRunLoopMode
    [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerModeth) userInfo:nil repeats:YES];
    NSThread * runLoopThread = [[NSThread alloc]initWithTarget:self selector:@selector(oneThread) object:nil];
    [runLoopThread start];
    [self performSelector:@selector(twoThread) onThread:runLoopThread withObject:nil waitUntilDone:YES];
 
    //给线程增加一个run loop 对这个线程进行保活
- (void)oneThread{   
//    这里如果waitUntilDone:NO 即不用等待callBack执行完成,直接执行下面的代码
//    如果waitUntilDone:YES即需要等待callBack执行完成后(如果执行完,线程就会释放,选择YES程序会崩溃,需要添加runloop进行线程保活),子线程才会继续执行后面的代码
        NSRunLoop * runloop = [NSRunLoop currentRunLoop];
        [runloop addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
        [runloop run];
}
- (void)twoThread{ 
    NSLog(@"线程通讯成功");
}

@interface ViewController ()
//dispatch_source_t 设置为成员变量,不然会立即释放
@property(nonatomic,strong) dispatch_source_t timer;

@end

    // 创建一个定时器(dispatch_source_t)
    /**
      何时开始执行第一个任务  DISPATCH_TIME_NOW(现在时间)
      1.0 * NSEC_PER_SEC 每隔多长时间执行一次
     */
    _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0));
    dispatch_source_set_timer(_timer, DISPATCH_TIME_NOW, 1.0*NSEC_PER_SEC, 0);
    // 设置回调
    dispatch_source_set_event_handler(_timer, ^{
        NSLog(@"设置回调");
    });
     // 启动定时器
    dispatch_resume(_timer);

//    控制器被干掉了之后,打印还在进行,使用下面方法进行关闭
//    dispatch_source_cancel(_timer);
上一篇下一篇

猜你喜欢

热点阅读