參考文獻
在ios專案中,有時會有一些花費時間較長的操作阻塞主線程,我們通常為了防止介面卡頓,將其放入子執行緒中執行。根據執行緒知識,如果子執行緒執行完分配的任務後,就會自動銷毀。
比如我們現在定義乙個執行緒,改寫它的dealloc方法,觀察它什麼時候銷毀
@implementation taythread-(
void
)dealloc
@end
在viewcontroller裡新建乙個taythread子執行緒,讓它去執行任務
@implementation viewcontroller-(
void
)viewdidload -(
void
)dosomething
@end
根據列印結果我們可以看到,在子執行緒執行完任務後執行緒自動銷毀。
而我們有時會需要經常在乙個子執行緒中執行任務,頻繁的建立和銷毀執行緒就會造成資源浪費,這時候就要用到runloop來使執行緒長時間存活了,我們稱之為執行緒保活
我們首先需要建立乙個runloop。
注意:runloop直接獲取就可以,沒有的話會在第一次獲取時建立;如果runloop 中的 modes 為空,或者要執行的mode裡沒有item,那麼runloop會直接在當前runloop中返回,並進入睡眠狀態。即dosomething改為:
根據列印結果可以知道,方法並沒有執行完畢。我們希望的是在子執行緒執行完任務後就睡覺等待被喚醒,這樣子寫相當於雖然該任務執行完了但是runloop一直卡在這裡,也不能去執行別的任務。顯而易見,這種辦法是不夠完美的。
官方文件中提到有三種啟動runloop的方法:
方法名介紹
中文翻譯
rununconditionally
無條件rununtildate
with a set time limit
設定時間限制
runmode:beforedate:
in a particular mode
在特定模式下
對於三種方法介紹總結如下:
檢視 run 方法的文件還可以知道,它的本質就是無限呼叫 runmode:beforedate: 方法,同樣地,rununtildate: 也會重複呼叫 runmode:beforedate:,區別在於它超時後就不會再呼叫
也就是說,只有runmode:beforedate:方法是單次呼叫,其他兩種都是迴圈呼叫
在處理事件之前,有兩種方法可以使執行迴圈退出:
如果你使用方法二或三來啟動 runloop,那麼在啟動的時候就可以設定超時時間。然而考慮到我們的目標是:「利用 runloop 進行執行緒保活」,所以我們希望對執行緒和它的 runloop 有最精確的控制,比如在完成任務後立刻結束,而不是依賴於超時機制
根據文件描述,我們有乙個 cfrunloopstop() 方法來手動結束乙個 runloop
注意:cfrunloopstop() 方法只會結束當前的 runmode:beforedate: 呼叫,而不會結束後續的呼叫
通過以上關於runloop啟動和關閉的方法分析,我們大概有這樣乙個思路:
我們想要控制runloop,就需要使用runmode:beforedate:方法,因為其他兩種方法乙個無法停止乙個只能依賴超時機制
cfrunloopstop() 方法只會結束當前的一次的runmode:beforedate:方法呼叫,我們必須再做點什麼
針對以上疑問,有以下解答:
首先,因為runmode:beforedate:方法是單次呼叫,我們需要給它加上乙個迴圈,否則呼叫一次就over了,和不使用runloop的效果大同小異
這個迴圈的條件可以預設設定為yes,當呼叫stop方法時,執行cfrunloopstop() 方法並且將迴圈條件改為no,就可以使迴圈停止,runloop退出
**長這樣:
@inte***ce viewcontroller (
)@property
(strong, nonatomic) taythread *athread;
@property
(assign, nonatomic, getter=isstoped) bool stopped;
@end
@implementation viewcontroller-(
void
)viewdidload
nslog
(@"ok");
}];[
self
.athread start];}
-(void
)touchesbegan:
(nsset
>
*)touches withevent:
(uievent *
)event
// 子執行緒需要執行的任務-(
void
)dosomething -(
void
)stop
// 用於停止子執行緒的runloop-(
void
)stopthread -(
void
)dealloc
後來又發現還存在一些問題,如果將上述**寫入乙個newviewcontroller,當該viewcontroller已經dealloc時,執行緒並沒有死,這就造成了記憶體洩漏了。我這個執行緒是為了這個viewcontroller而活的,viewcontroller都死掉了,執行緒怎麼能還活著呢,下面是修改後的
#import "newviewcontroller.h"
#import "taythread.h"
@inte***ce newviewcontroller (
)@property
(strong, nonatomic) taythread *athread;
@property
(assign, nonatomic, getter=isstoped) bool stopped;
@end
@implementation newviewcontroller-(
void
)viewdidload
nslog
(@"ok");
}];[
self
.athread start];}
-(void
)touchesbegan:
(nsset
>
*)touches withevent:
(uievent *
)event
// 子執行緒需要執行的任務-(
void
)dosomething -(
void
)stop
}// 用於停止子執行緒的runloop-(
void
)stopthread -(
void
)dealloc -(
void
)back
深入研究 runloop 與執行緒保活
ios開發-使用runloop實現執行緒保活、執行緒常駐
如何實現執行緒保活
有兩種方案 第一種 提公升優先順序 降低程序被殺死的概率 執行緒的優先順序 a.前台程序 b.可見程序 c.服務程序 d.後台程序 e.空程序 1.利用activity 提公升許可權 監聽手機鎖屏事件 在螢幕鎖屏的時候啟動乙個 1畫素的 activity,在使用者解鎖時將 activity 銷毀,注...
ios 執行緒休眠 iOS執行緒保活(常駐執行緒)
介紹 在日常的ios開發中,遇到卡頓也是在所難免,一般卡頓是由於主線程處理耗時長的操作而造成執行緒一直在阻塞,那麼我們可以去建立子執行緒,把耗時操作放在子執行緒去做,這樣是完全沒問題。這樣就會有乙個問題,子執行緒處理完操作之後就會被銷毀,想再處理其他事情,必須再開啟新的子執行緒。如果想要乙個子執行緒...
跑步app保活 android APP保活機制
摘要 1,從官網上可以看出google為了系統更加流暢以及優化記憶體,google做了很大的處理,在手機暗屏或者睡眠狀態就停止後台執行 若要保持service的常駐,需要做一些前端的活動,notification重要屬性 notification.flags notification.flag no...