Objective-c并发编程 -- NSRunLoop

RunLoop概念

  • 运行循环
  • 内部是由do-while循环实现的

RunLoop 作用

  • 保证程序的持续运行
  • 处理App的各种事件(滑动, 定时器, selector)
  • 节省CPU资源, 提高程序性能
  • 默认启动的RunLoop是跟主线程相关联的, 主要处理与主线程相关的事件

RunLoop 循环图

RunLoop 对象

  • Foundation: NSRunLoop (OC语言)
  • Core Foundation: CFRunLoopRef (C语言)

RunLoop 与线程

  • 每条线程都有唯一的一个与之对应的RunLoop对象
  • 主线程的RunLoop随着程序已自动创建好, 但是子线程的RunLoop需要手动创建
  • 获得主线程的RunLoop的方法是 [NSRunLoop mainRunLoop];
  • 创建子线程的RunLoop的方法是[NSRumLoop currentRunLoop]; // apple不允许创建RunLoop

Runloop Mode

CFRunLoopModeRef 介绍

  • CFRunLoopModeRef 代表了RunLoop的运行模式
  • 一个RunLoop可以包含若干个Mode, 每个Mode包含若干个 Source/Timer/Observer
  • 每次RunLoop启动时, 只能指定其中的一个Mode, 这个Mode被称作为currentMode
  • 如果需要切换Mode, 需要退出RunLoop,再重新指定一个Mode进入,这样做的原因是为了分离不同的Source/Timer/Observer, 让其互不影响

CFRunLoopModeRef类型

  1. kCFRunLoopDefaultMode: App的默认Mode, 通常主线程是在该Mode下运行
  2. UITrackingRunLoopMode: 界面跟踪Mode, 用于ScrollView追踪触摸滑动, 保证界面滑动时, 不收其它Mode影响
  3. UIInitializationRunLoopMode: 在刚启动时App进入的第一个Mode, 启动完成后就不再使用
  4. GSEventReciveRunLoopMode: 接收系统事件的内部Mode, 一般不用
  5. kCFRunLoopCommonModes: 这是一个占位用的Mode, 不是真正的Mode

CFRunLoopTimerRef

  • 是基于时间的触发器 (NSTimer)
    // 自动加在RunLoop下 可以直接运行
//    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
    
    NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
    
    // 添加
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
// NSRunLoopCommonModes = UITrackingRunLoopMode + NSDefaultRunLoopMode

CFRunLoopSourceRef

  • 是事件源(输入源)
  • 按官方文档分类
  1. Port-Based Sources 从其它线程或内核发出来的
  2. Custom Input Sources 自定义的
  3. CoCoa Perform Selector Sources
  • 按函数调用栈分类
  1. Sources0: 非基于Port的
  2. Sources0:基于Port, 通过其他线程或者内核通信, 接受,分发系统时间

CFRunLoopObserverRef

  • 观察者, 能够监听RunLoop的状态的改变
/* Run Loop Observer Activities */
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
    kCFRunLoopEntry = (1UL << 0),                 // 即将进入RunLoop
    kCFRunLoopBeforeTimers = (1UL << 1),      // 即将处理Timer
    kCFRunLoopBeforeSources = (1UL << 2),    // 即将处理 Sources
    kCFRunLoopBeforeWaiting = (1UL << 5),    // 即将进入休眠
    kCFRunLoopAfterWaiting = (1UL << 6),      // 即将从休眠中唤醒 
    kCFRunLoopExit = (1UL << 7),                  // 即将推出
    kCFRunLoopAllActivities = 0x0FFFFFFFU   // 活跃中
};
  • 给runLoop添加观察者)
    // 给runLoop添加观察者  需要CF类
    CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
        NSLog(@"----%lu----", activity)
    });
    
    CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode);

RunLoop内部逻辑

转载于:https://my.oschina.net/jasper1987/blog/831108

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值