Run loop基础

来源:互联网 发布:淘宝网现状 编辑:程序博客网 时间:2024/05/29 10:14

Run loop就像它的名字一样,是你thread中的一个循环并对收到的事件进行处理。你可以把它理解成一个函数,线程启动run loop就是调用了类似这样的一个方法:

function loop() {    initialize();    do {        var message = get_next_message();        process_message(message);    } while (message != quit);}

Run loop从两个不同的事件源中接收消息。Input sources(CFRunLoopSource)投递异步消息,通常来自于另一个thread或另一个应用程序。Timer sources(CFRunLoopTimer)当在计划的时间或重复的时间间隔内投递同步消息。两种事件源都使用应用程序指定的处理方式对到达的事件进行处理。下图展示了run loop和不同的事件源结构。
这里写图片描述

下来是Run Loop的使用场合:
1. 使用port或是自定义的input source来和其他线程进行通信
2. 在线程(非主线程)中使用timer
3. 使用 performSelector…系列(如performSelectorOnThread, …)
4. 使用线程执行周期性工作

NSTimer的工作原理:
一个 NSTimer 注册到 RunLoop 后,RunLoop 会为其重复的时间点注册好事件。例如 10:00, 10:10, 10:20 这几个时间点。RunLoop为了节省资源,并不会在非常准确的时间点回调这个Timer。Timer 有个属性叫做 Tolerance (宽容度),标示了当时间点到后,容许有多少最大误差。
如果某个时间点被错过了,例如执行了一个很长的任务,则那个时间点的回调也会跳过去,不会延后执行。就比如等公交,如果 10:10 时我忙着玩手机错过了那个点的公交,那我只能等 10:20 这一趟了。

NSTimer在子线程:
主线程的Run loop在应用程序的main函数中已经启动了,所以我们在主线程中使用定时器是可以正常运行的。

UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]))

在子线程中如果想要定时器能正常工作的话,那必须启动子线程的run loop:

- (void)threadBody{    //此种方式创建的timer已经添加至runloop中//    [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(doTask:) userInfo:nil repeats:YES];//    [[NSRunLoop currentRunLoop] run];    //此种方式创建的timer没有添加至runloop中    NSTimer *timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(doTask:) userInfo:nil repeats:YES];    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];    [[NSRunLoop currentRunLoop] run];}- (void)doTask:(NSTimer *)t{    NSLog(@"sss");}

当然,这里只是很简单的介绍了一下run loop的原理,以为NSTimer在run loop中运行的原理,想深入学习RunLoop的可以去这里面看一下这里写链接内容

0 0
原创粉丝点击