GCD中除了主要的Dispatch Queue外胶背,還有較次要的Dispatch Source势腮。它是BSD系內(nèi)核慣有功能kqueue的包裝买乃。
kqueue是在XUN內(nèi)核中發(fā)生各種事件時(shí)锈死,在應(yīng)用程序編程方執(zhí)行處理的技術(shù)珍剑。其CPU負(fù)荷非常小掸宛,盡量不占用資源。kqueue可以說是應(yīng)用程序處理XUN內(nèi)核中發(fā)生的各種事件的方法中最優(yōu)秀的一種招拙。
Dispatch Source的種類:
1唧瘾、DISPATCH_SOURCE_TYPE_DATA_ADD 變量增加
2、DISPATCH_SOURCE_TYPE_DATA_OR 變量 OR
3别凤、DISPATCH_SOURCE_TYPE_MACH_SEND MACH端口發(fā)送
4饰序、DISPATCH_SOURCE_TYPE_MACH_RECV MACH端口接收
5、DISPATCH_SOURCE_TYPE_MEMORYPRESSURE 內(nèi)存壓力 (注:iOS8后可用)
6规哪、DISPATCH_SOURCE_TYPE_PROC 檢測到與進(jìn)程相關(guān)的事件
7求豫、DISPATCH_SOURCE_TYPE_READ 可讀取文件映像
8、DISPATCH_SOURCE_TYPE_SIGNAL 接收信號(hào)
9诉稍、DISPATCH_SOURCE_TYPE_TIMER 定時(shí)器
10蝠嘉、DISPATCH_SOURCE_TYPE_VNODE 文件系統(tǒng)有變更
11、DISPATCH_SOURCE_TYPE_WRITE 可寫入文件映像
Dispatch Source類型比較多杯巨,下面記錄定時(shí)器功能的實(shí)現(xiàn)蚤告。
實(shí)現(xiàn)定時(shí)器功能非常簡單,實(shí)現(xiàn)如下:
@interface ZBViewController ()
@property (nonatomic, strong) dispatch_source_t timer;
@end
- (void)viewDidLoad {
[super viewDidLoad];
//1.創(chuàng)建類型為 定時(shí)器類型的 Dispatch Source
//1.1將定時(shí)器設(shè)置在主線程
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
//1.2設(shè)置定時(shí)器每一秒執(zhí)行一次
dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), 1ull * NSEC_PER_SEC, 0);
//1.3設(shè)置定時(shí)器執(zhí)行的動(dòng)作
dispatch_source_set_event_handler(_timer, ^{
//在這里實(shí)現(xiàn)業(yè)務(wù)邏輯...
NSLog(@"來打我吖76徘 !");
});
//2.啟動(dòng)定時(shí)器
dispatch_resume(_timer);
// Do any additional setup after loading the view.
}
上述簡單代碼就已經(jīng)實(shí)現(xiàn)了定時(shí)器功能仍源, 注意:將定時(shí)器寫成屬性心褐,是因?yàn)閮?nèi)存管理的原因,使用了dispatch_source_create
方法笼踩,這種方法GCD是不會(huì)幫你管理內(nèi)存的檬寂。之前我就忘記了,寫完戳表,高高興興的去運(yùn)行---->What?已經(jīng)啟動(dòng)了為什么定時(shí)器無效呢桶至?現(xiàn)在想想...MDZZ!
dispatch_source_create(dispatch_source_type_t type,
uintptr_t handle,
unsigned long mask,
dispatch_queue_t _Nullable queue)
第一個(gè)參數(shù):dispatch_source_type_t type
為設(shè)置GCD源方法的類型,前面已經(jīng)列舉過了匾旭。
第二個(gè)參數(shù):uintptr_t handle
Apple的API介紹說镣屹,暫時(shí)沒有使用,傳0即可价涝。
第三個(gè)參數(shù):unsigned long mask
Apple的API介紹說女蜈,使用DISPATCH_TIMER_STRICT
,會(huì)引起電量消耗加劇色瘩,畢竟要求精確時(shí)間伪窖,所以一般傳0即可,視業(yè)務(wù)情況而定居兆。
第四個(gè)參數(shù):dispatch_queue_t _Nullable queue
隊(duì)列覆山,將定時(shí)器事件處理的Block提交到哪個(gè)隊(duì)列之上∧嗥埽可以傳Null簇宽,默認(rèn)為全局隊(duì)列。注意:當(dāng)提交到全局隊(duì)列的時(shí)候吧享,時(shí)間處理的回調(diào)內(nèi)魏割,需要異步獲取UI線程,更新UI...不過這好像是常識(shí)钢颂,又啰嗦了...
dispatch_source_set_timer(dispatch_source_t source,
dispatch_time_t start,
uint64_t interval,
uint64_t leeway);
第一個(gè)參數(shù):dispatch_source_t source
......不用說了
第二個(gè)參數(shù):dispatch_time_t start
, 定時(shí)器開始時(shí)間钞它,類型為 dispatch_time_t
,其API的abstract標(biāo)明可參照dispatch_time()
和dispatch_walltime()
殊鞭,同為設(shè)置時(shí)間遭垛,但是后者為“鐘表”時(shí)間,相對(duì)比較準(zhǔn)確钱豁,所以選擇使用后者耻卡。dispatch_walltime(const struct timespec *_Nullable when, int64_t delta)
,參數(shù)when可以為Null,默認(rèn)為獲取當(dāng)前時(shí)間牲尺,參數(shù)delta為增量卵酪,即獲取當(dāng)前時(shí)間的基礎(chǔ)上,增加X秒的時(shí)間為開始計(jì)時(shí)時(shí)間谤碳,此處傳0即可溃卡。
第三個(gè)參數(shù):uint64_t interval
,定時(shí)器間隔時(shí)長蜒简,由業(yè)務(wù)需求而定瘸羡。
第四個(gè)參數(shù):uint64_t leeway
, 允許誤差搓茬,此處傳0即可犹赖。
dispatch_source_set_event_handler(dispatch_source_t source,
dispatch_block_t _Nullable handler)
第一個(gè)參數(shù):dispatch_source_t source
队他,...不用說了。
第二個(gè)參數(shù):dispatch_block_t _Nullable handler
峻村,定時(shí)器執(zhí)行的動(dòng)作麸折,需要處理的業(yè)務(wù)邏輯Block。
dispatch_resume(_timer)
定時(shí)器創(chuàng)建完成并不會(huì)運(yùn)行粘昨,需要主動(dòng)去觸發(fā)垢啼,也就是調(diào)用上述方法。
調(diào)度源提供了源事件的處理回調(diào)张肾,同時(shí)也提供了取消源事件處理的回調(diào)芭析,使用非常方便。
dispatch_source_set_cancel_handler(dispatch_source_t source,
dispatch_block_t _Nullable handler)
對(duì)吞瞪,Dispatch Source是可以取消的馁启。
Dispatch Source還有很多種類型,后續(xù)繼續(xù)學(xué)習(xí)吧尸饺!