理解 OC 中 RunLoop

本文深入浅出地介绍了Objective-C中的RunLoop机制,包括RunLoop的基本概念、与线程的关系、不同模式的作用及应用场景,同时还提供了解决卡顿问题的具体实现方案。

理解 OC 中 RunLoop

什么是RunLoop?

可以简单理解为,让程序保持运行的一个while循环,这个循环内监听各种事件(如触摸事件、performSelector、定时器NSTimer等),没有事件的时候睡眠,从而有效的利用CPU(只有在有事件的时候才用CPU,没事件的时候睡眠)

不管RunLoop有多复杂,其本质就是上面所说的:一个循环,有事件的时候处理事件,无事件的时候休眠(这里的睡眠是指用户态切换到内核态,这样的休眠线程是被挂起的,不会再占用cpu资源)。

RumLoop与线程有如下关系:

  • 一个线程只有一个RunLoop对象
  • 主线程的RunLoop默认已经创建好了,而子线程的需要手动创建。
  • RunLoop在第一次获取时创建,在线程结束时销毁。

我们验证一下,在main函数返回之前,打印一下:

int main(int argc, char *argv[])
{
    NSString *appDelegateClassName;
    @autoreleasepool {
        // Setup code that might create autoreleased objects goes here.
        appDelegateClassName = NSStringFromClass([AppDelegate class]);
    }
    int ret = UIApplicationMain(argc, argv, nil, appDelegateClassName);
    NSLog(@"after ret");
    return ret;
}

结果没有打印,这说明主进程已经进入了一个RunLoop主了,主进程不结束,就跳不出RunLoop,也就执行不了之后的打印。

我们打印一下主线程的RunLoop试试:

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"%@", [NSRunLoop currentRunLoop]);
}

// 打印结果(只取关键信息):
// CFRunLoop 0x600001704700
// current mode = kCFRunLoopDefaultMode,

这说明主线程在一个RunLoop中,并且当前的运行模式是kCFRunLoopDefaultMode

这样感觉RunLoop很简单,但它又很复杂,因为要考虑的因素有很多,比如各种事件的处理顺序,定时器、多线程等等

对于一个复杂问题,解决方法之一就是抽象,苹果为解决上面的问题,抽象出了RunLoop对象,RunLoop中包含多个Mode类,每个mode类中包含若干个 Source,Observer和Timer类,关系如下:

在这里插入图片描述

Mode是RunLoop的运行模式,有五类:

kCFRunLoopDefaultMode //App的默认Mode,通常主线程是在这个M
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值