1、RunLoop相關類
CFRunLoopRef:代表RunLoop的對象
CFRunLoopModeRef:RunLoop的運行模式
CFRunLoopSourceRef:就是RunLoop模型圖中提到的輸入源/事件源
CFRunLoopTimerRef:就是RunLoop模型圖中提到的定時源
CFRunLoopObserverRef:觀察者,能夠監聽RunLoop的狀態改變
一個RunLoop對象(CFRunLoopRef)中包含若干個運行模式(CFRunLoopModeRef)。而每一個運行模式下又包含若干個輸入源(CFRunLoopSourceRef)、定時源(CFRunLoopTimerRef)、觀察者(CFRunLoopObserverRef)。
2、 CFRunLoopRef
Core Foundation
CFRunLoopGetCurrent(); // 獲得當前線程的RunLoop對象
CFRunLoopGetMain(); // 獲得主線程的RunLoop對象
當然,在Foundation框架下獲取RunLoop對象類的方法如下:
Foundation
[NSRunLoop currentRunLoop]; // 獲得當前線程的RunLoop對象
[NSRunLoop mainRunLoop]; // 獲得主線程的RunLoop對象
3、CFRunLoopModeRef
系統默認定義了多種運行模式(CFRunLoopModeRef),如下:
kCFRunLoopDefaultMode:App的默認運行模式,通常主線程是在這個運行模式下運行
UITrackingRunLoopMode:跟蹤用戶交互事件(用于 ScrollView 追蹤觸摸滑動,保證界面滑動時不受其他Mode影響)
UIInitializationRunLoopMode:在剛啟動App時第進入的第一個 Mode,啟動完成后就不再使用
GSEventReceiveRunLoopMode:接受系統內部事件,通常用不到
kCFRunLoopCommonModes:偽模式,不是一種真正的運行模式(后邊會用到)
4、 CFRunLoopTimerRef
// 定義一個定時器,約定兩秒之后調用self的run方法
NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
// 將定時器添加到當前RunLoop的NSDefaultRunLoopMode下
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
5、CFRunLoopObserverRef
CFRunLoopObserverRef可以監聽的狀態改變有以下幾種:
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
kCFRunLoopEntry = (1UL << 0),? ? ? ? ? ? ? // 即將進入Loop:1
kCFRunLoopBeforeTimers = (1UL << 1),? ? ? ? // 即將處理Timer:2
kCFRunLoopBeforeSources = (1UL << 2),? ? ? // 即將處理Source:4
kCFRunLoopBeforeWaiting = (1UL << 5),? ? ? // 即將進入休眠:32
kCFRunLoopAfterWaiting = (1UL << 6),? ? ? ? // 即將從休眠中喚醒:64
kCFRunLoopExit = (1UL << 7),? ? ? ? ? ? ? ? // 即將從Loop中退出:128
kCFRunLoopAllActivities = 0x0FFFFFFFU? ? ? // 監聽全部狀態改變
};
// 創建觀察者
CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
NSLog(@"監聽到RunLoop發生改變---%zd",activity);
});
// 添加觀察者到當前RunLoop中
CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode);
// 釋放observer,最后添加完需要釋放掉
CFRelease(observer);
6、ImageView推遲顯示
[self.imageView performSelector:@selector(setImage:) withObject:[UIImage imageNamed:@"tupian"] afterDelay:4.0 inModes:NSDefaultRunLoopMode];
7、 后臺常駐線程(很常用)
// 創建線程,并調用run1方法執行任務
self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(run1) object:nil];
// 開啟線程
[self.thread start];
- (void) run1
{
// 這里寫任務
NSLog(@"----run1-----");
// 添加下邊兩句代碼,就可以開啟RunLoop,之后self.thread就變成了常駐線程,可隨時添加任務,并交于RunLoop處理
[[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
// 測試是否開啟了RunLoop,如果開啟RunLoop,則來不了這里,因為RunLoop開啟了循環。
NSLog(@"未開啟RunLoop");
}