文档章节

Objective-c并发编程 -- NSRunLoop

Japer1987
 Japer1987
发布于 2017/02/03 00:38
字数 661
阅读 16
收藏 0

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内部逻辑

© 著作权归作者所有

Japer1987
粉丝 1
博文 40
码字总数 19747
作品 0
深圳
程序员
私信 提问
iPhone/Mac Objective-C内存管理教程和原理剖析(四)系统自动创建新的aut...

四 系统自动创建新的autorelease pool 在生成新的Run Loop的时候,系统会自动创建新的autorelease pool(非常感谢网友hhyytt和neogui的提醒)。注意,此处不同于xcode在新建项目时自动生成的...

Liuxz-aaa
2011/06/08
504
0
牛客网 iOS 题 107-126

### 牛客网 iOS 题 107-126 107.NSRunLoop 以下描述错误的是( ) RunLoop 并不是由系统自动控制的 有三类对象可以被 RunLoop 监控:sources,timers,observers 线程是默认启动 RunLoop 的 ...

木佥
2018/05/12
0
0
iPhone/Mac Objective-C内存管理教程和原理剖析 【四、系统自动创建新的autorelease pool】

四 系统自动创建新的autorelease pool 在生成新的Run Loop的时候,系统会自动创建新的autorelease pool(非常感谢网友hhyytt和neogui的提醒)。注意,此处不同于xcode在新建项目时自动生成的...

长平狐
2012/10/25
44
0
Objective-c中[signal sigabrt]问题

代码运行后出现下面的问题。 2014-10-30 23:18:45.673 L6-4Another[73662:2444037] -[Dog updateFromPath:]: unrecognized selector sent to instance 0x100409e40 2014-10-30 23:18:45.676 ......

xee
2014/10/31
2.6K
2
知其然亦知其所以然-NSOperation并发编程

对于iOS的并发编程, 用的最普遍的就是GCD了, GCD结合Block可以so easy的实现多线程并发编程. 但如果你看一些诸如AFNetworking, SDWebImage的源码, 你会发现它们使用的都是NSOperation, 纳尼?...

金小俊
2015/11/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

从0开始学FreeRTOS-(列表&列表项)-6

FreeRTOS列表&列表项的源码解读 第一次看列表与列表项的时候,感觉很像是链表,虽然我自己的链表也不太会,但是就是感觉很像。 在FreeRTOS中,列表与列表项使用得非常多,是FreeRTOS的一个数...

杰杰1号
29分钟前
4
0
Java的23种设计模式,详细讲解(一)

一、概述 设计模式是解决问题的方案,学习现有的设计模式可以做到经验复用。 拥有设计模式词汇,在沟通时就能用更少的词汇来讨论,并且不需要了解底层细节。 二、创建型 1. 单例(Singleton...

李红欧巴
45分钟前
5
0
android 使用asynctask结合fragment更新UI(另附线程池管理示例)

https://blog.csdn.net/qq_16064871/article/details/70767949

shzwork
46分钟前
3
0
SpringCloud实现分库分表模式下,数据库实时扩容方案

本文源码:GitHub·点这里 || GitEE·点这里 一、项目结构 1、工程结构 2、模块命名 shard-common-entity: 公共代码块shard-open-inte: 开放接口管理shard-eureka-7001: ...

知了一笑
47分钟前
5
0
js--时间切割装换工具类

<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title></title> <script type="text/javascript"> /* * 修改data原型对象Format方法 ......

zhengzhixiang
57分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部