runloop

1、runloop概念

字面意思:运行循环,其内部实现实际是do-while循环实现的

2、作用

保证程序的正常运行,处理APP的各种事件(滑动、定时器、selector),节省cpu资源,提高程序性能。

如果程序中没有runloop,则程序运行完,立马关闭退出。

而有runloop则程序相当于一个死循环,保证程序的正常运行。

int main(int argc ,char * argv[]){

do{

nslog(@"execute main function");

}while(1);

return 0;

}

OC代码中,在程序入口处,实际上是再UIApplicationMain函数内部中启动了一个runloop,所以UIApplicationMain函数中就一直没有返回值

,保证了程序的持续运行。

注意:默认启动的runloop是跟主线程相关的,处理主线程相关的事件。

3、runoop对象

ios中有两套API来访问和使用runloop

foundation框架下的NSRunloop 另一个是CORE Foundation框架下的 CFRunloopRef,其中NSRunloop是基于CFRunloopref的。

4、runloop 与线程

1》每条线程都有唯一一个与之对应的runloop

2》主线程的runloop随着程序以自动创建好,但是子线程的runloop需要手动创建。

3》获取住线程的runloop方法为:[nsrunloop mainrunloop];

4》创建子线程的runloop方法:[nsrunloop currentrunloop];

注意:苹果不允许创建runloop,只能通过上面两种方式获取runloop

5、runloop相关类


cfrunloopmoderef

cfrunloopmoderef代表runloop的运行模式

一个runloop可以办函若干个model,每个mode包含若干个source/timer/observer

每次启动runloop,只能制定其中的一个mode,这个mode为currentmode

如果需要切换mode,需呀退出runloop,再重新指定一个mode进入,这样做的原因是为了分离不同组的source/timer/

observer,让其互不影响

KCFRunloopDefaultMode :app的默认mode,通常主线程就是再该mode下运行。

UITrackRunLoopRefMode: 界面跟踪mode,用于scrollview追踪触摸滑动,保证界面滑动时,不受其他mode影响。

UIInitializationRunLoopMode:再刚启动app的时候进入的第一个mode,启动玩后不再使用

GSEventRecieveRunLoopMode:接受系统事件的内部Mode,通常情况下不用

KCFRunloopCommonModes:这是一个占位mode,不是真正的mode,有这个标记模式的有default  /  track

cfrunloopsourceref

事件源,也可称为输入源

官方文档:

1》port-based souces 从其他线程或内核发出的

2》custom input sources 自定义的

3》 cocoa perform selector sources 

函数调用栈分类:

1》sources0  非基于port

2》sources1 基于port ,通过其他线程或者内核通信,接收、分发系统事件

cfrunlooptimerref

基于时间的触发器,NSTimer

cfloopobserverref


- (void)observer{
    // 创建一个监听者
//    CFRunLoopObserverCreate(<#CFAllocatorRef allocator#>, <#CFOptionFlags activities#>, <#Boolean repeats#>, <#CFIndex order#>, <#CFRunLoopObserverCallBack callout#>, <#CFRunLoopObserverContext *context#>)

    // 使用下面这种方法
   /**
    第一个参数:(<#CFAllocatorRef allocator#>)分配存储空间
    第二个参数:(<#CFOptionFlags activities#>)要监听的状态(kCFRunLoopAllActivities)所有的状态
    第三个参数:(<#Boolean repeats#>)是否持续监听
    第四个参数:(<#CFIndex order#>)优先级
    第五个参数:回调

    */
   CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {

        switch (activity) {
            case kCFRunLoopEntry:
                NSLog(@"即将进入runloop");
                break;
            case kCFRunLoopBeforeTimers:
                NSLog(@"即将处理 Timer");
                break;
            case kCFRunLoopBeforeSources:
                NSLog(@"即将处理 Sources");
                break;
            case kCFRunLoopBeforeWaiting:
                NSLog(@"即将进入休眠");
                break;
            case kCFRunLoopAfterWaiting:
                NSLog(@"从休眠中唤醒loop");
                break;
            case kCFRunLoopExit:
                NSLog(@"即将退出runloop");
                break;

            default:
                break;
        }

    });


    // 给runloop添加监听者
    /**
     第一个参数:(<#CFRunLoopRef rl#>)要监听哪个runloop
     第二个参数:(<#CFRunLoopObserverRef observer#>)监听者
     第三个参数:(<#CFStringRef mode#>)要监听runloop在哪种运行模式下的状态

     */
    CFRunLoopAddObserver(CFRunLoopGetCurrent(),observer,kCFRunLoopDefaultMode);

    /// 这里可以自己写一个NSTimer实验一下

    // 释放runloop
    CFRelease(observer);
}
#凡是带有Create,Copy,Retain等字眼的函数,创建出来的对象,都要在最后做一次release操作
runloop逻辑处理:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值