iOS 知识整理--Runloop

目录

Runloop--概念

Runloop--获取Runloop对象

Runloop--与线程的关系

Runloop--五大相关类

Runloop--应用

Runloop--面试题

RunLoop--注意点

 


Runloop--概念

基本作用:

  1. 保持程序的持续运行
  2. 处理App中的各种事件(比如触摸事假、定时事件、selector事件)
  3. 节省CPU资源,提高程序性能:该做事时做事,改休息时休息。

iOS中有2套API来访问和使用Runloop:

  1. Foundation NSRunloop
  2. Core Foundation CFRunLoopRef

Runloop--获取Runloop对象

  • Foundation

[NSRunloop currentRunLoop];//获取当前线程的Runloop对象

[NSRunloop mainRunLoop];//获取主线程的Runloop对象

  • Core Foundation

CFRunloopGetCurrent();//获取当前线程的Runloop对象

CFRunLoopGetMain();//获取主线程的Runloop对象

  • 互相转化方法

mainRunLoop.getCFRunLoop

Runloop--与线程的关系

每条线程都有唯一的一个与之对应的Runloop对象

主线程的Runloop已经自动创建好了,子线程的Runloop需要手动创建

Runloop在第一次获取时创建,在线程结束时销毁

Runloop--五大相关类

Core Foundation 中关于 Runloop的5个类

  • CFRunLoopRef//本身
  • CFRunLoopModeRef//运行模式
  • CFRunLoopSourceRef//事件源输入源
  • CFRunloopTimerRef//定时器
  • CFRunLoopObserverRef//监听

CFRunLoopModeRef(运行模式)

CFRunLoopModeRef代表RunLoop的运行模式

  • 一个Runloop包含若干个Mode,每个Mode又包含若干个Source/Timer/Observer
  • 每次Runloop启动时,只能指定其中一个 Mode,这个Mode被称为CurrentMode
  • 如果需要切换Mode,只能退出Loop,再重新指定一个Mode进入
  • 这样做主要是为了分隔开不同组的Source/Timer/Observer,让其互不影响

系统默认注册了5个Mode:

  • kCFRunLoopDefaultMode:App默认Mode,通常主线程是在这个Mode下运行
  • UITrackingRunLoopMode:界面跟踪Mode,用于ScrollView追踪触摸滑动,保证界面滑动时不受其他Mode影响
  • UIIntiallizationRunLoopMode:在刚启动App时进入的第一个Mode,启动完成后就不再使用
  • GSEventReceiveRunLoopMode:接受系统事件的内部Mode,通常用不到
  • kCFRunLoopCommonModes:这是一个占位用的Mode,不是一种真正的Mode

CFRunLoopSourceRef(输入源)

是事件源(输入源)

  • Source0:非基于Port的(用户主动触发的事件,点击按钮,拖拽表格)
  • Source1:基于Port的(系统内部的消息事件)

CFRunLoopTimerRef(定时器)

CFRunLoopTimerRef是基于时间的触发器

基本上说的就是NSTimer

CFRunLoopObserverRef(观察者)

是观察者,能够监听RunLoop的改变状态

//创建监听者
/*
1.怎么分配存储空间
2.要监听的状态 kCFRunLoopAllActivities所有的状态
3.是否持续监听
4.优先级,总是传0
5.当状态改变时候回调
*/

    CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
        /*
         kCFRunLoopEntry = (1UL << 0),即将进入runloop
         kCFRunLoopBeforeTimers = (1UL << 1),即将处理timer事件
         kCFRunLoopBeforeSources = (1UL << 2),即将处理source事件
         kCFRunLoopBeforeWaiting = (1UL << 5),即将进入睡眠
         kCFRunLoopAfterWaiting = (1UL << 6),被唤醒
         kCFRunLoopExit = (1UL << 7),runloop退出
         kCFRunLoopAllActivities = 0x0FFFFFFFU
         */
        switch (activity) {
            case kCFRunLoopEntry:
                NSLog(@"即将进入runloop");
                break;
            case kCFRunLoopBeforeTimers:
                NSLog(@"即将处理timer事件");
                break;
            case kCFRunLoopBeforeSources:
                NSLog(@"即将处理source事件");
                break;
            case kCFRunLoopBeforeWaiting:
                NSLog(@"即将进入睡眠");
                break;
            case kCFRunLoopAfterWaiting:
                NSLog(@"被唤醒");
                break;
            case kCFRunLoopExit:
                NSLog(@"runloop退出");
                break;
            default:
                break;
        }      
    });

/*
1.要监听哪个runloop
2.观察者
3.运行模式
     NSDefaultRunLoopMode = kCFRunLoopDefaultMode
     NSRunLoopCommonModes = kCFRunLoopCommonModes
*/

    CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode);
}

 

Runloop--应用

NSTimer

ImageView显示

PerformSelector

常驻线程

自动释放池

NSRunLoop *runLoop = [NSRunLoop currentRunLoop];

[runLoop addPort:[NSPort port] forMode:NSDefaultRunLoopMode];

[runLoop run];

Runloop--面试题

1.什么是RunLoop?

从字面意思看是运行循环、跑圈

其实它内部就是do-while循环,在这个循环内部不断地处理各种任务(比如Source、Timer、Observer)一个线程对应一个RunLoop,主线程的RunLoop默认已经开启,子线程的RunLoop得手动启动(调用runloop方法)

RunLoop只能选择一个Mode启动,如果当前Mode中没有任何Source(Sources0、Sources1)、Timer,那么就直接退出RunLoop

 

2.自动释放池什么时候释放?

第一次创建:启动runloop

最后一次销毁:runloop退出的时候

其他时候创建和销毁:当runloop即将睡眠的时候销毁之前的释放池,重新创建一个新的

 

3.在开发中如何使用RunLoop?什么应用场景?

开启一个常驻线程(让一个子线程不进入消亡状态,等待其他线程发来消息,处理其他事件)

可以控制定时器在特定模式下执行

可以让某些事件(行为、任务)在特定模式下执行

可以添加Observer 监听RunLoop的状态,比如监听点击事件的处理(在所有点击事件之前做一些事情)

 

RunLoop--注意点

1.子线程runloop默认不创建

NSRunloop *loop= [NSRunloop currentRunLoop];//创建子线程runloop

[Loop run];//开启runloop

2.在runloop中有多个运行模式,但是runloop只能选择一种模式运行

3.mode里面至少有一个timer或者source

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值