RunLoop 初识(2.逻辑流程以及实际应用)

RunLoop 相关逻辑流程

上图是笔者从网上找到的一张 RunLoop 运行的相关流程逻辑图。具体来说主要执行逻辑是这样的:

  • 1、通知观察者 RunLoop 已经启动。
  • 2、通知观察者即将要开始定时器。
  • 3、通知观察者任何即将启动的非基于端口的源。
  • 4、启动任何准备好的非基于端口的源(Source0)。
  • 5、如果基于端口的源(Source1)准备好并处于等待状态,进入步骤9。
  • 6、通知观察者线程进入休眠状态。
  • 7、将线程置于休眠状态,知道下面的任一事件发生才唤醒线程。
    . 某一事件到达基于端口的源
    . 定时器启动。
    . RunLoop 设置的时间已经超时。
    . RunLoop 被唤醒。
  • 8、通知观察者线程将被唤醒。
  • 9、处理未处理的事件。
    .如果用户定义的定时器启动,处理定时器事件并重启RunLoop。进入步骤2。
    .如果输入源启动,传递相应的消息。
    .如果RunLoop被显示唤醒而且时间还没超时,重启RunLoop。进入步骤2
  • 10、通知观察者RunLoop结束。

 

RunLoop 实际应用

Run Loop应用实践

Run Loop主要有以下三个应用场景:

  • 维护线程的生命周期,让线程不自动退出,isFinished为Yes时退出。
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
while (!self.isCancelled && !self.isFinished) {
    @autoreleasepool {
            [runLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:3]];
    }
}
  • 创建常驻线程,执行一些会一直存在的任务。该线程的生命周期跟App相同
@autoreleasepool {
        NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
        [runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
        [runLoop run];
}
  • 在一定时间内监听某种事件,或执行某种任务的线程
    如下代码,在30分钟内,每隔30s执行onTimerFired:。这种场景一般会出现在,如我需要在应用启动之后,在一定时间内持续更新某项数据。
@autoreleasepool {
    NSRunLoop * runLoop = [NSRunLoop currentRunLoop];
    NSTimer * udpateTimer = [NSTimer timerWithTimeInterval:30
                                                    target:self
                                                  selector:@selector(onTimerFired:)
                                                  userInfo:nil
                                                   repeats:YES];
    [runLoop addTimer:udpateTimer forMode:NSRunLoopCommonModes];
    [runLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:60*30]];
}
  • AFNetworking中RunLoop的创建
+ (void)networkRequestThreadEntryPoint:(id)__unused object {
    @autoreleasepool {
        [[NSThread currentThread] setName:@"AFNetworking"];

        NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
         // 这里主要是监听某个 port,目的是让这个 Thread 不会回收
        [runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode]; 
        [runLoop run];
    }
}

+ (NSThread *)networkRequestThread {
    static NSThread *_networkRequestThread = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        _networkRequestThread =
        [[NSThread alloc] initWithTarget:self
                                selector:@selector(networkRequestThreadEntryPoint:)
                                  object:nil];
        [_networkRequestThread start];
    });
    return _networkRequestThread;
}

参考地址:https://www.jianshu.com/p/7bc36b111774

参考地址: https://www.cnblogs.com/zy1987/p/4582466.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值