iOS RunLoop与NSTimer RunLoop与多线程
作者:互联网
文章目录
1.RunLoop与NSTimer
- 我们的线程,或tableView,正常情况下是运行在default模式下。当我们对tableView进行滑动的时候,会进行一个Mode的切换,会切换到Tracking模式上。多个mode是为了对timer/observer/source进行一个隔离。 timer默认添加到default模式,这个时候如果切换打Tracking模式,定时器就不会在生效了
1.1 CFRunLoopAddTimer源码分析
源码下载地址:https://opensource.apple.com/tarballs/CF/CF-855.17.tar.gz
- commonMode是把一些mode打上mode的标记,可以把timer等同步到多个mode中
2.RunLoop与多线程
- 线程与RunLoop是什么关系
- 自己创建的线程需要自己手动创建RunLoop
2.1 怎样实现一个常驻线程
- CFERunLoopGetCurrent(),这个方法本身,如果当前线程没有RunLoop,系统会为我们创建
- RunLoop如果没有事件源需要处理的话,默认情况下,他是不能维持自己事件循环的,就会直接退出了。所以我们需要给他添加一个Port或者Source来维持他的事件循环机制
2.1.1 实例代码MCObject.m
- 在while循环中,可能会进入休眠状态
#import "MCObject.h"
@implementation MCObject
static NSThread *thread = nil;
// 标记是否要继续事件循环
static BOOL runAlways = YES;
+ (NSThread *)threadForDispatch{
if (thread == nil) {
@synchronized(self) {
if (thread == nil) {
// 线程的创建
thread = [[NSThread alloc] initWithTarget:self selector:@selector(runRequest) object:nil];
[thread setName:@"com.imooc.thread"];
//启动
[thread start];
}
}
}
return thread;
}
+ (void)runRequest
{
// 创建一个Source
CFRunLoopSourceContext context = {0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
CFRunLoopSourceRef source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
// 创建RunLoop,同时向RunLoop的DefaultMode下面添加Source
CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
// 如果可以运行
while (runAlways) {
@autoreleasepool {
// 令当前RunLoop运行在DefaultMode下面,第二个参数,运行到指定事件结束,1.0e10为无穷大。第三个参数,资源被处理后是否返回
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0e10, true);
}
}
// 某一时机 静态变量runAlways = NO时 可以保证跳出RunLoop,线程退出。source移除后,runloop会退出
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
CFRelease(source);
}
@end
标签:NULL,thread,MCObject,iOS,source,线程,多线程,RunLoop 来源: https://blog.csdn.net/baidu_40537062/article/details/118892085