RunLoop的實質是一個死循環(huán)诗越,用于保證程序的持續(xù)運行匹厘,只有當程序退出的時候才會結束
1。保證線程的長時間存活
2诸衔。處理App中的各種事件(觸摸盯漂、定時器、Selector事件)
3笨农。節(jié)省CPU資源就缆,提高程序性能(該做事做事,沒事做休息)
RunLoop相關類:
CFRunLoopRef:代表RunLoop的對象
CFRunLoopModeRef:RunLoop的運行模式
CFRunLoopSourceRef:就是RunLoop模型圖中提到的輸入源/事件源
CFRunLoopTimerRef:就是RunLoop模型圖中提到的定時源
CFRunLoopObserverRef:觀察者谒亦,能夠監(jiān)聽RunLoop的狀態(tài)改變
RunLoop模式常用有3個:
NSDefaultRunLoopMode->默認模式竭宰,主線程中默認是NSDefaultRunLoopMode
UITrackingRunLoopMode->視圖滾動模式,RunLoop會處于該模式下
NSRunLoopCommonModes->并不是真正意義上的Mode份招,是一個占位用的“Mode”切揭,默認包含了NSDefaultRunLoopMode和UITrackingRunLoopMode兩種模式
runloop和線程的關系:
主線程Runloop已經(jīng)創(chuàng)建好了,子線程的runloop需要手動創(chuàng)建 锁摔;一條線程對應一個RunLoop對象廓旬,每條線程都有唯一一個與之對應的RunLoop對象。一般來講谐腰,一個線程一次只能執(zhí)行一個任務孕豹,執(zhí)行完成后線程就會退出
runloop的實際使用:
1涩盾。RunLoop運行模式對NSTimer定時器的影響。
NSTimer的定時器是受運行模式影響的励背,而開發(fā)中我們有時候徹底去除這種影響春霍,很顯然,NSTimer定時器不能做到這點叶眉,這時址儒,我們可以使用GCD的定時器。
2衅疙。ImageView推遲顯示-->實現(xiàn)圖片加載性能優(yōu)化
當界面中含有UITableView莲趣,而且每個UITableViewCell里邊都有圖片。這時候當我們滾動UITableView的時候饱溢,如果有一堆的圖片需要顯示妖爷,那么可能會出現(xiàn)卡頓的現(xiàn)象。
2.1. 監(jiān)聽UIScrollView的滾動
因為UITableView繼承自UIScrollView理朋,所以我們可以通過監(jiān)聽UIScrollView的滾動絮识,實現(xiàn)UIScrollView相關delegate即可。
2.2. 利用PerformSelector設置當前線程的RunLoop的運行模式
利用 performSelector 方法為UIImageView調(diào)用 setImage: 方法嗽上,并利用 inModes 將其設置為RunLoop下NSDefaultRunLoopMode運行模式次舌。
[self.imageView performSelector:@selector(setImage:) withObject:[UIImage imageNamed:@"tupian"] afterDelay:4.0 inModes:NSDefaultRunLoopMode];
這樣我們就實現(xiàn)了在拖動完之后,在延遲顯示UIImageView兽愤。
3彼念。后臺常駐線程
我們在開發(fā)應用程序的過程中,如果后臺操作特別頻繁浅萧,經(jīng)常會在子線程做一些耗時操作(下載文件逐沙、后臺播放音樂等),我們最好能讓這條線程永遠常駐內(nèi)存洼畅。
- (void)viewDidLoad {
[super viewDidLoad];
// 創(chuàng)建線程吩案,并調(diào)用run1方法執(zhí)行任務
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開啟了循環(huán)芋浮。
NSLog(@"未開啟RunLoop");
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
// 利用performSelector抱环,在self.thread的線程中調(diào)用run2方法執(zhí)行任務
[self performSelector:@selector(run2) onThread:self.thread withObject:nil waitUntilDone:NO];
}
- (void) run2{
NSLog(@"----run2------");
}
經(jīng)過運行測試,除了之前打印的 ----run1----- ,每當我們點擊屏幕镇草,都能調(diào)用 ----run2------ 濒憋。
這樣我們就實現(xiàn)了常駐線程的需求。