1.NSRunLoop
今天做項(xiàng)目的時候豪椿,要想開啟一個計(jì)時器監(jiān)控系統(tǒng)的時間篮昧,用到了NSRunLoop,一般來說暇昂,是用CFRunLoopGetCurrent這個函數(shù)來獲取當(dāng)前線程的runLoop的。但是如果應(yīng)用在沒有開啟子線程的情況下伴嗡,那么當(dāng)前線程也就是主線程急波。也就是說CFRunLoopGetCurrent函數(shù)獲取的runLoop()是當(dāng)前線程的,也就是主線程的瘪校。在這種情況下澄暮,一旦run后,根本關(guān)閉不了阱扬,因?yàn)楂@取到的是的runLoop(假設(shè)是A)泣懊,是主線程的runLoop。而你想要關(guān)閉的是子線程的runLoop(假設(shè)是B)麻惶,根本都沒有獲取到子線程的runLoop馍刮。所以關(guān)閉的代碼并沒有起到任何作用。再說用踩,也沒有權(quán)限停止主線程的runLoop,在程序沒有退出之前渠退,是沒法關(guān)閉停止主線程的忙迁。
參考文獻(xiàn):NSThread 脐彩、NSRunLoop 和 Dispatch Queue - kmyhy的專欄 - 博客頻道 - CSDN.NET
后來的做法是:新開了一個線程(子線程),每個線程中都自帶RunLoop姊扔,用CFRunLoopGetCurrent()函數(shù)可以獲得當(dāng)前線程的RunLoop惠奸。(這樣就可以保證獲取的是不會是主線程的runLoop)
ps:如果RunLoop中沒有任何源,RunLoop不會運(yùn)行恰梢。我們可以為這個RunLoop添加新的源佛南。
2.
會發(fā)現(xiàn)頁面跳轉(zhuǎn)不了,并出現(xiàn)這些警告:Only run on the main thread
原因:真機(jī)環(huán)境下嵌言,UI的處理必須是單線程的嗅回,所以當(dāng) 在一個已存在的UI上切換新的UI時,會出現(xiàn)Only run on the main thread 錯誤摧茴。告訴你绵载,只能在主線程上運(yùn)行。
因?yàn)槲议_啟的是一個子線程苛白,利用子線程監(jiān)聽到一定的時間后娃豹,就進(jìn)行賬號主線,從主菜單頁面強(qiáng)行跳轉(zhuǎn)到登錄頁面购裙。所以產(chǎn)生這樣的警告懂版。
解決辦法:在單線程里面操作,進(jìn)行跳轉(zhuǎn):dispatch_async(dispatch_get_main_queue(), ^{
LoginViewController *loginController = [[LoginViewController alloc]init];
[self presentViewController:loginController animated:NO completion:nil];
});
3.
盡管如此躏率,你會發(fā)現(xiàn)還是無法跳轉(zhuǎn)躯畴,會出現(xiàn)這樣的警告:
Warning: Attempt to present <loginViewController>on <mainMenuController>??which is already presenting (null)
出現(xiàn)這樣的警告民鼓,首先是因?yàn)槲覐闹鞑藛雾撁妫╩ainMenuController)到登陸頁面(loginViewController)不是push過去的,而是presenting過去的蓬抄。而此時在主菜單頁面上剛好有一個選擇的彈框摹察。如下圖:
而這個彈框也是presenting到主菜單頁面的。所以必須先要關(guān)掉(diss)這個彈框倡鲸,才能跳轉(zhuǎn)到登錄頁面供嚎。如下圖:
先關(guān)掉這個,就可以了峭状。?