1:runloop是什麼?html
runloop是一個循環,它是程序運行的基石;主要功能有: 可以保持程序的持續運行 處理App中的各類事件(好比觸摸事件、定時器事件、Selector事件) 提升程序性能:有事件須要處理就運行起來;沒有任務的時候處於睡眠狀態;節省CPU資源;
UIApplication 中一直開啓一個runloop來保證程序正常運行.ios
2:runloop與線程之間的關係app
每條線程都有惟一的一個與之對應的RunLoop對象(主線程runloop默認開啓,子線程runloop須要手動開啓)RunLoop在第一次獲取時建立,在線程結束時銷燬
3.runloop相關類介紹:oop
CFRunLoopModeRef: 一個RunLoop包含若干個 Mode,每一個Mode又包含若干個Source/Timer/Observer 每次RunLoop啓動時,只能指定其中一個 Mode,這個Mode被稱做 CurrentMode(當且僅當指定一個mode) 若是須要切換Mode,只能退出Loop,再從新指定一個Mode進入 這樣作主要是爲了分隔開不一樣組的Source/Timer/Observer,讓其互不影響 ModeType: kCFRunLoopDefaultMode:App的默認Mode,一般主線程是在這個Mode下運行 UITrackingRunLoopMode:界面跟蹤 Mode,用於 ScrollView 追蹤觸摸滑動,保證界面滑動時不受其餘Mode影響 UIInitializationRunLoopMode: 在剛啓動 App 時第進入的第一個 Mode,啓動完成後就再也不使用 GSEventReceiveRunLoopMode: 接受系統事件的內部 Mode,一般用不到 kCFRunLoopCommonModes: 這是一個佔位用的Mode,不是一種真正的Mode(是幾種mode的集合) CFRunLoopSourceRef CFRunLoopSourceRef是事件源(輸入源)能夠分爲兩類: Port-Based Sources (基於端口,跟其餘線程交互,經過內核發佈的消息) Custom Input Sources (自定義類型) Cocoa Perform Selector Sources (performSelector…方法) 包含兩種事件:Source0(大可能是自定義方法), Source1(基於系統) Source0: event事件,只含有回調,須要先調用CFRunLoopSourceSignal(source),將這個 Source 標記爲待處理,而後手動調用 CFRunLoopWakeUp(runloop) 來喚醒 RunLoop。 Source1: 包含了一個 mach_port 和一個回調,被用於經過內核和其餘線程相互發送消息,能主動喚醒 RunLoop 的線程 CFRunLoopObserverRef: observer:顧名思義就是一個觀察者;來觀察runloop不一樣的狀態 /* Run Loop Observer Activities */ typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) { kCFRunLoopEntry = (1UL << 0), //進入runloop kCFRunLoopBeforeTimers = (1UL << 1), //開始處理timer事件以前 kCFRunLoopBeforeSources = (1UL << 2), //開始處理source事件錢 kCFRunLoopBeforeWaiting = (1UL << 5), //開始睡眠以前 kCFRunLoopAfterWaiting = (1UL << 6), //喚醒以後 kCFRunLoopExit = (1UL << 7), //退出 kCFRunLoopAllActivities = 0x0FFFFFFFU };
3.runloop處理事件的步驟:
e004412fc56ab75a4e5d53275a4bd41c.jpg
4.runloop實際應用性能
1.滑動scrollView輪播圖輪播失效,是因爲定時器只運行在NSDefaultRunLoopMode下,一旦RunLoop進入其餘模式,這個定時器就不會工做.而滑動的時候是trakingMode;解決方法:timer 添加到runloop的commonMode 2.當滑動scrollView時候改變imageView圖片 (1)能夠監聽scrollView滑動事情來作 (2) [imageView performSelector:@selector(setImage:) withObject:[UIImage imageNamed:@"trakingModeImageName"] afterDelay:3.0 inModes:@[UITrackingRunLoopMode]]; 3.常駐線程 (1)粗暴的方法 while(YES){} (2)添加source [[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode]; 啓動RunLoop:[[NSRunLoop currentRunLoop] run]; 退出:[NSThread exit];
參考內容:
http://ios.jobbole.com/85635/...
https://developer.apple.com/l...
http://opensource.apple.com/s...線程