iOS基础知识梳理 - Runloop

2019-08-04  本文已影响0人  babyloveblues

消息循环

消息循环在主线程上的使用

  1. 消息
    我们可以简单的把消息理解为用户的输入事件
  2. 循环

什么是RunLoop

RunLoop目的

事件类型

如何使用

(1)创建输入源(NSTimer为例)
(2)指定该事件(源)在循环运行中的模式,并且加入循环

    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait;
屏幕快照 2019-08-04 下午7.12.08.png

下面的代码示例可以比喻为,一个患牙病的人应该去综合性医院而不应该去妇产科医院就诊

- (void)demo{
    
    // 创建NSTimer
    NSTimer *timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(task) userInfo:nil repeats:YES];
    // 把定时源加入到当前线程下消息循环中
    // 参数1: 定时源
    // 参数2: NSDefaultRunLoopMode

    /**
     现象:
     NSDefaultRunLoopMode 拖动界面,定时源不运行
     NSRunLoopCommonModes 拖动界面不受影响(KCFRunloopDefaultMode,UITrackingRunloopMode都是其中的一种)
     没有拖动界面 KCFRunloopDefaultMode
     拖动界面 UITrackingRunloopMode
     */
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
    
}

使用总结
(1)创建消息
(2)把消息放进循环
(3)在于循环的模式匹配的时候,消息运行

消息循环在子线程上的使用

特点:自线程默认不开启消息循环,主线程默认开启消息循环

// 子线程的消息循环
-(void)demo2{
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(task2) object:nil];
    thread.name = @"新创建的子线程";
    [thread start];
    
    // 往指定线程的消息循环中加入源
    [self performSelector:@selector(addTask) onThread:thread withObject:nil waitUntilDone:NO];
}

-(void)task{
    NSLog(@"task is running");
}

-(void)task2{
    
    NSLog(@"%@",[NSRunLoop currentRunLoop].currentMode);
    // 输出当前的线程
    NSLog(@"task2 is running %@", [NSThread currentThread]);
    
    // 开启消息循环 使用run方法无法停止消息循环
    // 方法一
    // [[NSRunLoop currentRunLoop] run];
    // 方法二 改方法受机器性能的影响很大,很老的机器并不一定可以两秒钟内停止这个runloop
    // [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]];
    // 方法三 apple推荐的方式
    //    BOOL shouldKeepRunning = YES; //全局的
    NSRunLoop *theRL = [NSRunLoop currentRunLoop];
    while (shouldKeepRunning && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]) {
        
    }
    
    NSLog(@"runloop over!!!");
    
}

-(void)addTask{
    
    NSLog(@"addTask is running");
    
}
上一篇 下一篇

猜你喜欢

热点阅读