CFRunLoop
来源:互联网 发布:淘宝过户服务费 编辑:程序博客网 时间:2024/04/30 10:21
Cocoa会涉及到Run Loops的
系统级:
GCD,mach kernel,block,pthread
应用层:
NSTimer,UIEvent,Autorelease,
NSObject(NSDelayedPerforming),
NSObject(NSThreadPerformAddition),
CADisplayLink,CATransition,CAAnimation,
dispatch_get_main_queue()(GCD中dispatch到main queue的block会被dispatch到main RunLoop执行),
NSPort,NSURLConnection,
AFNetworking(这个第三方网络请求框架使用在开启新线程中添加自己的run loop监听事件)
构成
Thread包含一个CFRunLoop,一个CFRunLoop包含一种CFRunLoopMode,mode包含CFRunLoopSource,CFRunLoopTimer和CFRunLoopObserver。
CFRunLoopMode
RunLoop只能运行在一种mode下,如果要换mode当前的loop也需要停下重启成新的。利用这个机制,ScrollView过程中NSDefaultRunLoopMode的mode会切换UITrackingRunLoopMode来保证ScrollView的流畅滑动不受只能在NSDefaultRunLoopMode时处理的事件影响滑动。同时mode还是可定制的。
NSDefaultRunLoopMode:默认,空闲状态
UITrackingRunLoopMode:ScrollView滑动时
UIInitializationRunLoopMode:启动时
NSRunLoopCommonModes:Mode集合 Timer计时会被scrollView的滑动影响的问题可以通过将timer添加到NSRunLoopCommonModes来解决
//将timer添加到NSDefaultRunLoopMode中[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES];//然后再添加到NSRunLoopCommonModes里NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES];[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
CFRunLoopTimer
NSTimer是对RunLoopTimer的封装
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay inModes:(NSArray *)modes;+ (CADisplayLink *)displayLinkWithTarget:(id)target selector:(SEL)sel;- (void)addToRunLoop:(NSRunLoop *)runloop forMode:(NSString *)mode;
CFRunLoopSource
source0:处理如UIEvent,CFSocket这样的事件
source1:Mach port驱动,CFMachport,CFMessagePort
CFRunLoopObserver
Cocoa框架中很多机制比如CAAnimation等都是由RunLoopObserver触发的。observer到当前状态的变化进行通知。
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) { kCFRunLoopEntry = (1UL << 0),kCFRunLoopBeforeTimers = (1UL << 1), kCFRunLoopBeforeSources = (1UL << 2), kCFRunLoopBeforeWaiting = (1UL << 5), kCFRunLoopAfterWaiting = (1UL << 6), kCFRunLoopExit = (1UL << 7),kCFRunLoopAllActivities = 0x0FFFFFFFU};
使用RunLoop的案例
AFNetworking
使用NSOperation+NSURLConnection并发模型都会面临NSURLConnection下载完成前线程退出导致NSOperation对象接收不到回调的问题。
AFNetWorking解决这个问题的方法是按照官方的guidhttps://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html#//apple_ref/occ/instm/NSURLConnection/initWithRequest:delegate:startImmediately:上写的NSURLConnection的delegate方法需要在connection发起的线程runloop中调用,
于是AFNetWorking直接借鉴了Apple自己的一个Demohttps://developer.apple.com/LIBRARY/IOS/samplecode/MVCNetworking/Introduction/Intro.html的实现方法单独起一个global thread,内置一个runloop,所有的connection都由这个runloop发起,回调也是它接收,不占用主线程,也不耗CPU资源。
+ (void)networkRequestThreadEntryPoint:(id)__unused object { @autoreleasepool { [[NSThread currentThread] setName:@"AFNetworking"]; NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; [runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode]; [runLoop run]; }}+ (NSThread *)networkRequestThread { static NSThread *_networkRequestThread = nil; static dispatch_once_t oncePredicate; dispatch_once(&oncePredicate, ^{ _networkRequestThread = [[NSThread alloc] initWithTarget:self selector:@selector(networkRequestThreadEntryPoint:) object:nil]; [_networkRequestThread start]; }); return _networkRequestThread;}
类似的可以用这个方法创建一个常驻服务的线程。click
TableView中实现平滑滚动延迟加载图片
利用CFRunLoopMode的特性,可以将图片的加载放到NSDefaultRunLoopMode的mode里,这样在滚动UITrackingRunLoopMode这个mode时不会被加载而影响到。
UIImage *downloadedImage = ... ;[self.avatarImageView performSelector:@selector(setImage:) withObject:downloadedImage afterDelay:0 inModes:@[NSDefaultRunLoopMode]];
click
本文摘自
- https://github.com/ming1016/study/wiki/CFRunLoop#%E4%BD%BF%E7%94%A8runloop%E7%9A%84%E6%A1%88%E4%BE%8B
- http://blog.ibireme.com/2015/05/18/runloop/#base
- CFRunLoop
- CFRunLoop
- CFRunLoop
- CFRunLoop
- CFRunLoop介绍
- CFRunLoop介绍
- CFRunLoop学习
- Swift CFRunLoop
- A CFRunLoop object
- CFRunLoop介绍(转载)
- [iOS] CFRunLoop示例总结
- CFRunLoop介绍(转载)
- [iOS] CFRunLoop示例总结
- NSThread创建CFRunLoop
- CFRunLoop示例总结
- NSThread创建CFRunLoop
- CFRunLoop介绍(转载)
- CFRunloop 源码阅读笔记
- hdoj-5706-GirlCat
- Java集合接口
- iOS -- CALayer之锚点
- Keras学习笔记1——win7__keras框架搭建步骤(Theano)
- Linux命令-df、du
- CFRunLoop
- oracle 导出导入不含数据的空库
- Thread类的使用
- 基于SIM900A-GPRS模块的远程文件传输实例
- 三、C++ 类型转换构造函数
- Collection.max min最大最小值 集合(list set map)
- Qt之操作数据库(SQLite) [此博文包含图片] (2013-12-09 16:58:05) 转载 ▼ 标签: qt sqlite qsqldatabase qsqlquery qsqlerro
- 菜鸟的安卓之路。2016.06.02
- 如何储存图