RunLoop深度探究以及有关面试题
首先什么是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的基本作用:
- 保持程序的持续运行
- 处理App中的各种事件(比如触摸事件、定时器事件等)
- 节省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的运行逻辑
- 通知Observers:进入Loop
- 通知Observers:即将处理Timers
- 通知Observers:即将处理Sources
- 处理Blocks
- 处理Source0(可能会再次处理Blocks)
- 如果存在Source1,就跳转到第8步
- 通知Observers:开始休眠(等待消息唤醒)
- 通知Observers:结束休眠(被某个消息唤醒) 处理Timer 或者处理GCD Async To Main Queue 或者 处理Source1
- 处理Blocks
- 根据前面的执行结果,决定如何操作: 回到第02步 或者 退出Loop
- 通知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] 腾讯云.<深度强化学习>面试题汇总 [2] Reinforcement Learning遇到的一些强化学习面试问题 [3] 知乎.再励学习面试真题 深度强化学习报道 来 ...
- 【深度探究css】--- vertical-align
提醒:内容与图片较多...... 前言:由于vertical-align这个属性w3c似乎也并没有给出比较完整的对齐规则,只是对各个值的解释(或者我的姿势不对???????).所以下面使用大量的测试去 ...
- CVPR2018 | R(2+1)D结构:视频动作识别中的时空卷积深度探究
本文 是C3D作者Du Tran+IDT作者Heng Wang发表在CVPR2018的新作.来自Facebook Resaerch &Dartmouth Colledge.文章主要对是动作识别 ...
- 心智模型学习:深度探究用户需求的why
心智模型学习:深度探究用户需求的why 最近看到一种用户研究的方法叫"攀梯术",很有启发,原文比较理论,我试着翻译一下.它主要用在一对一深访的场景下,可以探究用户对产品功能/特性的 ...
- 深度学习秋招面试题集锦(一)
这部分的面试题包含C++基础知识.python基础.概率相关.智力题相关.算法相关以及深度学习相关.后续还会不断补充,欢迎大家查阅! C++后台开发面试常见问题汇总 Q1 : C++虚函数表剖析. A ...
- 深度学习试题_深度学习秋招面试题集锦(一)
这部分的面试题包含C++基础知识.python基础.概率相关.智力题相关.算法相关以及深度学习相关.后续还会不断补充,欢迎大家查阅! C++后台开发面试常见问题汇总 Q1 : C++虚函数表剖析. A ...
- 深度学习笔试、面试题 三
1.声明1:可以通过将所有权重初始化为0 来训练网络. 声明2:可以通过将偏差初始化为0来很好地训练网络 以上哪些陈述是真实的? A 1对2错 B 1错2对 C 1和2都对 D 1和2都错 正确答 ...
- 深度学习---算法岗面试题
● 深度学习了解多少,有看过底层代码吗?caffe,tf? ● 除了GMM-HMM,你了解深度学习在语音识别中的应用吗? 参考回答: 讲了我用的过DNN-HMM,以及与GMM-HMM的联系与区别:然后 ...
- 景联文科技:深度探究自动驾驶重要方向——车路协同
不久前,国内首部关于智能网联汽车管理的法规--<深圳经济特区智能网联汽车管理条例>获得深圳市人大常委会会议表决通过,并于8月1日起开始施行.该条例对车路协同基础设施进行了明确规定.根据&l ...
最新文章
- 九、springboot整合rabbitMQ
- 一种通过scout ESI和CNN解码EEG运动想象四分类任务的新方法
- python命令行解析_python命令行解析函数
- CDH 6 安装 Hbase 二级索引 Solr + Key-Value Store Indexer
- 如何使用开源工具制作YouTube系列
- 拓扑排序——杂物(洛谷 P1113)
- Jmeter 时间函数工具汇总
- MySQL Table is marked as crashed and should be repaired
- wince 错误 Error: failed PB timebomb check
- Sniffer Pro 4.7.5注册不成功问题(unable to communicate with server)
- 一般论文发表流程有哪些
- linux 查看tps命令,Linux系统一些系统查看指令
- 教程|教你如何给你的头像添加一个好看的国旗
- KVM实验二 pepsi-wyl
- 推挽电路介绍、设计与分析
- 2023年,前端开发就业前景好吗?
- 基于JAVA宠物用品交易网站计算机毕业设计源码+系统+lw文档+部署
- mysql等保测评命令_安全计算环境-二级等级保护测评指导和自动化脚本
- 小程序分销商城开发功能
- JAVA项目的目录结构分析
热门文章
- (转载+ 修改) 深入理解UIWindow
- 安卓关于fragment切换后继续运行的问题!
- MC新手入门(五十)------服务器连接 一
- 惊闻VeryCD的电驴下载部分即将关闭
- winlogon.exe应用程序错误的解决方法
- 出现java.lang.IllegalArgumentException异常
- Ubuntu解决Nvidia驱动缺失导致的HDMI无法输出问题
- Python requests 多线程抓取 出现HTTPConnectionPool Max retires exceeded异常
- 出现should be mapped with insert=“false“ update=“false“的解决方法
- 【vue】使用localStorage解决vuex在页面刷新后数据被清除的问题