也來談談CFRunLoop(NSRunLoop)
說來,我忘東西還真是飛快。
前一個月自認為把RunLoop研究得比較透徹了,但因為沒有在專案中實際使用的緣故,到現在竟然都快忘了,我必須得把它記錄下來,以後忘記了我還可以在這裡找回來再看看。
下面是測試程式碼:
- (void)viewDidLoad { [super viewDidLoad]; //這裡偷個懶,直接使用performSelectorInBackground來建立一個執行緒,並執行configRunLoop方法 [self performSelectorInBackground:@selector(configRunLoop) withObject:nil]; UIButton* __button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [__button1 setTitle:@"Fire Event" forState:UIControlStateNormal]; //觸發事件啟動RunLoop [__button1 addTarget:self action:@selector(triggerEvent) forControlEvents:UIControlEventTouchUpInside]; __button1.frame = CGRectMake(0, 0, 100, 80); [self.view addSubview:__button1]; UIButton* __button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [__button2 setTitle:@"Stop RunLoop" forState:UIControlStateNormal]; //RunLoop週期完成後自動退出執行緒 [__button2 addTarget:self action:@selector(stopRunloop) forControlEvents:UIControlEventTouchUpInside]; __button2.frame = CGRectMake(110, 0, 120, 80); [self.view addSubview:__button2]; } - (void)stopRunloop{ _shouldStop = YES; } - (void)triggerEvent{ if (CFRunLoopIsWaiting(_runLoopRef)) { NSLog(@"RunLoop 正在等待事件輸入"); //新增輸入事件 CFRunLoopSourceSignal(_source); //喚醒執行緒,執行緒喚醒後發現由事件需要處理,於是立即處理事件 CFRunLoopWakeUp(_runLoopRef); }else { NSLog(@"RunLoop 正在處理事件"); //新增輸入事件,當前正在處理一個事件,當前事件處理完成後,立即處理當前新輸入的事件 CFRunLoopSourceSignal(_source); } } //此輸入源需要處理的後臺事件 static void fire(void* info __unused){ NSLog(@"我現在正在處理後臺任務"); sleep(5); } - (void)configRunLoop{ //這裡獲取到的已經是某個子執行緒了哦,不是主執行緒哦 _tThread = [NSThread currentThread]; //這裡也是這個子執行緒的RunLoop哦 _runLoopRef = CFRunLoopGetCurrent(); bzero(&_source_context, sizeof(_source_context)); //這裡建立了一個基於事件的源 _source_context.perform = fire; _source = CFRunLoopSourceCreate(NULL, 0, &_source_context); //將源新增到當前RunLoop中去 CFRunLoopAddSource(_runLoopRef, _source, kCFRunLoopCommonModes); while (!_shouldStop) { NSLog(@"RunLoop 開始執行"); //每次RunLoop只執行10秒,每10秒做一次檢測,如果沒有需要處理的後臺任務了,就讓此執行緒自己終止,不用暴力Kill CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, NO); NSLog(@"RunLoop 停止執行"); } _tThread = nil; }
這裡是更詳細的說明和解釋
附件是Demo的完整程式碼
相關文章
- 也來談談人工智慧的罪與罰人工智慧
- 也來談談無法刪除db link的問題
- [宇塵埃]也來談談到底什麼是中臺?
- 外行假裝內行,我也來談談SAP BAPI和BADIAPI
- 也談元件化元件化
- 也談鏈路劫持
- [譯] 2018 來談談 Web ComponentWeb
- 也談goroutine排程器Go
- 也談一談最近“基因編輯”這個事情吧
- 來談談限流-RateLimiter原始碼分析MIT原始碼
- 一起來談談 Spring AOP!Spring
- 簡單來談談Unicode與emojiUnicode
- 也談如何寫一個Webserver(-)WebServer
- 來談談限流-從概念到實現
- Android 之 “只是想來談談 Handler 機制”Android
- 也談如何實現bind、apply、callAPP
- 也談如何寫一個Webserver(三)WebServer
- 也談SAP系統優缺點
- 也談談內卷化、996和程式設計師的發展996程式設計師
- 面試官:來談談限流-RateLimiter原始碼分析面試MIT原始碼
- 85後來談談我們怎麼養老?
- 《經濟學人》也談 Python:它會是我們的未來嗎?Python
- 談談近況,談談自由職業,談談“金飯碗”
- OpenAI o1 模型到來後,談談提示詞工程的未來OpenAI模型
- 再談 PHP 未來之路PHP
- 從996.icu來談一談如何高效支配時間996
- 《糖豆人》--是時候談談它的未來了
- 【經驗心得】談一談我IT行業未來的方向行業
- 【譯】談談“typeof null為object”這一bug的由來NullObject
- 也淺談下分散式儲存要點分散式
- 我來談談“人工智慧”這個詞給我帶來了哪些想法人工智慧
- 談談PromisePromise
- 談談RaftRaft
- 恆訊科技談談:雲遊戲的發展以及未來?遊戲
- 大齡碼農那些事——也談996.ICU996
- 談談 Web 安全Web
- 談談壓測
- 談談遞迴遞迴
- 談一談PromisePromise