首先什么是runloop?

顾名思义,运行循环,在程序运行中做一些事情。下面就是一个runloop,让程序不会马上退出,保持运行状态

int main(int argc, char * argv[]) {NSString * appDelegateClassName;@autoreleasepool {// Setup code that might create autoreleased objects goes here.appDelegateClassName = NSStringFromClass([AppDelegate class]);}return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}

RunLoop的基本作用:

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

iOS中有2套API来访问和使用RunLoop,Foundation中的NSRunLoop和Core Foundation的CFRunLoopRef,NSRunLoop是基于CFRunLoopRef的一层OC包装,CFRunLoopRef是开源的,https://opensource.apple.com/tarballs/CF/在这里可以查看。

RunLoop与线程的关系

  • 每条线程都有唯一的一个与之对应的RunLoop对象
  • RunLoop保存在一个全局的Dictionary里,线程作为key,RunLoop作为value
  • 线程刚创建时并没有RunLoop对象,RunLoop会在第一次获取它时创建
  • RunLoop会在线程结束时销毁
  • 主线程的RunLoop已经自动获取(创建),子线程默认没有开启RunLoop

Core Foundation中关于RunLoop的5个类

  • CFRunLoopRef
  • CFRunLoopModeRef
  • CFRunLoopSourceRef
  • CFRunLoopTimerRef
  • CFRunLoopObserverRef

  • CFRunLoopModeRef代表RunLoop的运行模式
  • 一个RunLoop包含若干个Mode,每个Mode又包含若干个Source0/Source1/Timer/Observer
  • RunLoop启动时只能选择其中一个Mode,作为currentMode
  • 如果需要切换Mode,只能退出当前Loop,再重新选择一个Mode进入
  • 如果Mode里没有任何Source0/Source1/Timer/Observer,RunLoop会立马退出

常见的两种model,kCFRunLoopDefaultMode(NSDefaultRunLoopMode):App的默认Mode,通常主线程是在这个Mode下运行,UITrackingRunLoopMode:界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响

RunLoop的运行逻辑

  1. 通知Observers:进入Loop
  2. 通知Observers:即将处理Timers
  3. 通知Observers:即将处理Sources
  4. 处理Blocks
  5. 处理Source0(可能会再次处理Blocks)
  6. 如果存在Source1,就跳转到第8步
  7. 通知Observers:开始休眠(等待消息唤醒)
  8. 通知Observers:结束休眠(被某个消息唤醒) 处理Timer 或者处理GCD Async To Main Queue 或者 处理Source1
  9. 处理Blocks
  10. 根据前面的执行结果,决定如何操作: 回到第02步 或者 退出Loop
  11. 通知Observers:退出Loop

runloop运行原理:是从用户态转到了内核态,在内核态等待消息,有消息就唤醒线程,没有就让线程休眠。

下面是runloop一个实际应用,线程保活,为了方便看是否销毁了线程,写了个FGThread继承了NSThread,实际上直接nsthread就可以了。

@interface FGPermenantThread : NSObject- (void)executeWith:(void (^)(void))task;- (void)stop;@end
@interface FGThread : NSThread@end
@implementation FGThread- (void)dealloc{NSLog(@"%s",__func__);
}@end
@interface FGPermenantThread ()@property (strong, nonatomic) FGThread *thread;
@property (assign ,nonatomic) BOOL isStopped;
@end
@implementation FGPermenantThread- (instancetype)init{if(self = [super init]){self.isStopped = NO;__weak typeof(self) weakSelf = self;self.thread = [[FGThread alloc] initWithBlock:^{NSLog(@"----begin");[[NSRunLoop currentRunLoop] addPort:[[NSPort alloc] init] forMode:NSDefaultRunLoopMode];if(weakSelf.isStopped && weakSelf){[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];}NSLog(@"----end");}];[self.thread start];}return self;
}- (void)dealloc{NSLog(@"%s",__func__);[self stop];
}#pragma mark -- public methods
- (void)executeWith:(void (^)(void))task{if(!self.thread || !task) return;[self performSelector:@selector(__execute:) onThread:self.thread withObject:task waitUntilDone:NO];
}- (void)stop{if(!self.thread) return;[self performSelector:@selector(__stop) onThread:self.thread withObject:nil waitUntilDone:YES];
}#pragma mark -- private methods
- (void)__stop{self.isStopped = YES;CFRunLoopStop(CFRunLoopGetCurrent());self.thread = nil;
}- (void)__execute:(void (^)(void))task{task();
}
@end

RunLoop深度探究以及有关面试题相关推荐

  1. 《深度强化学习》面试题汇总

    原文出处: [1] 腾讯云.<深度强化学习>面试题汇总 [2] Reinforcement Learning遇到的一些强化学习面试问题 [3] 知乎.再励学习面试真题 深度强化学习报道 来 ...

  2. 【深度探究css】--- vertical-align

    提醒:内容与图片较多...... 前言:由于vertical-align这个属性w3c似乎也并没有给出比较完整的对齐规则,只是对各个值的解释(或者我的姿势不对???????).所以下面使用大量的测试去 ...

  3. CVPR2018 | R(2+1)D结构:视频动作识别中的时空卷积深度探究

    本文 是C3D作者Du Tran+IDT作者Heng Wang发表在CVPR2018的新作.来自Facebook Resaerch &Dartmouth Colledge.文章主要对是动作识别 ...

  4. 心智模型学习:深度探究用户需求的why

    心智模型学习:深度探究用户需求的why 最近看到一种用户研究的方法叫"攀梯术",很有启发,原文比较理论,我试着翻译一下.它主要用在一对一深访的场景下,可以探究用户对产品功能/特性的 ...

  5. 深度学习秋招面试题集锦(一)

    这部分的面试题包含C++基础知识.python基础.概率相关.智力题相关.算法相关以及深度学习相关.后续还会不断补充,欢迎大家查阅! C++后台开发面试常见问题汇总 Q1 : C++虚函数表剖析. A ...

  6. 深度学习试题_深度学习秋招面试题集锦(一)

    这部分的面试题包含C++基础知识.python基础.概率相关.智力题相关.算法相关以及深度学习相关.后续还会不断补充,欢迎大家查阅! C++后台开发面试常见问题汇总 Q1 : C++虚函数表剖析. A ...

  7. 深度学习笔试、面试题 三

    ​ 1.声明1:可以通过将所有权重初始化为0 来训练网络. 声明2:可以通过将偏差初始化为0来很好地训练网络 以上哪些陈述是真实的? A 1对2错 B 1错2对 C 1和2都对 D 1和2都错 正确答 ...

  8. 深度学习---算法岗面试题

    ● 深度学习了解多少,有看过底层代码吗?caffe,tf? ● 除了GMM-HMM,你了解深度学习在语音识别中的应用吗? 参考回答: 讲了我用的过DNN-HMM,以及与GMM-HMM的联系与区别:然后 ...

  9. 景联文科技:深度探究自动驾驶重要方向——车路协同

    不久前,国内首部关于智能网联汽车管理的法规--<深圳经济特区智能网联汽车管理条例>获得深圳市人大常委会会议表决通过,并于8月1日起开始施行.该条例对车路协同基础设施进行了明确规定.根据&l ...

最新文章

  1. 九、springboot整合rabbitMQ
  2. 一种通过scout ESI和CNN解码EEG运动想象四分类任务的新方法
  3. python命令行解析_python命令行解析函数
  4. CDH 6 安装 Hbase 二级索引 Solr + Key-Value Store Indexer
  5. 如何使用开源工具制作YouTube系列
  6. 拓扑排序——杂物(洛谷 P1113)
  7. Jmeter 时间函数工具汇总
  8. MySQL Table is marked as crashed and should be repaired
  9. wince 错误 Error: failed PB timebomb check
  10. Sniffer Pro 4.7.5注册不成功问题(unable to communicate with server)
  11. 一般论文发表流程有哪些
  12. linux 查看tps命令,Linux系统一些系统查看指令
  13. 教程|教你如何给你的头像添加一个好看的国旗
  14. KVM实验二 pepsi-wyl
  15. 推挽电路介绍、设计与分析
  16. 2023年,前端开发就业前景好吗?
  17. 基于JAVA宠物用品交易网站计算机毕业设计源码+系统+lw文档+部署
  18. mysql等保测评命令_安全计算环境-二级等级保护测评指导和自动化脚本
  19. 小程序分销商城开发功能
  20. JAVA项目的目录结构分析

热门文章

  1. (转载+ 修改) 深入理解UIWindow
  2. 安卓关于fragment切换后继续运行的问题!
  3. MC新手入门(五十)------服务器连接 一
  4. 惊闻VeryCD的电驴下载部分即将关闭
  5. winlogon.exe应用程序错误的解决方法
  6. 出现java.lang.IllegalArgumentException异常
  7. Ubuntu解决Nvidia驱动缺失导致的HDMI无法输出问题
  8. Python requests 多线程抓取 出现HTTPConnectionPool Max retires exceeded异常
  9. 出现should be mapped with insert=“false“ update=“false“的解决方法
  10. 【vue】使用localStorage解决vuex在页面刷新后数据被清除的问题