利用GCD線程技術,加入MainDispatchQueue隊列,它會将任務插入主線程的RunLoop當中去執行,是以顯然是個串行隊列,我們可以使用它來更新UI。關鍵是app切換到背景它還在正常運作。不過它運作的時間不是無限的,是在背景存活3分鐘(這個是app獨立運作的情況下是背景存活三分鐘,在Xcode運作應用連接配接真機調試這個線程一直活着。)。當然你重新切換到前台時這個線程就又活了。由于它已經在主線程了,不能使用dispatch_sync(dispatch_get_main_queue(), ^{回主線程刷線UI否則崩潰。就是這種起線程的方式隻能重新整理一次UI。
下面是一個測試GCD線程使用MainDispatchQueue證明它在背景能正常運作的代碼,做一個單例或頁面,在代碼中調用test函數,可以看到,它在背景還照常打日志。這個加入主線程的函數調用時,由于它一直獨占cpu并且由于程式再sleep是以無法重新整理UI,是以點選按鈕無效。看來它的使用是很有局限性的:
//測試加入GCD的MainDispatchQueue隊列裡的線程在背景仍舊可以運作三分鐘
-(void)test
{
FLDDLogDebug(@"測試加入GCD的MainDispatchQueue隊列線程在背景仍舊可以運作");
dispatch_async(dispatch_get_main_queue(), ^{
for(NSInteger i = 0; ; i++)
{
sleep(1);
FLDDLogDebug(@"test:%ld", (long)i);
}
});
}
它能解決應用切換到背景,NSTimer無法實時計時的問題。再也不用通過幾個變量記錄時間,切換到前台再重新整理時間顯示了。
下面是記錄app在背景存活時間的部分日志:
2018/12/19 10:45:53:537 ViewController.m:-[ViewController test]_block_invoke:31 Debug:test:12
2018/12/19 10:45:54:538 ViewController.m:-[ViewController test]_block_invoke:31 Debug:test:13
2018/12/19 10:48:55:352 ViewController.m:-[ViewController test]_block_invoke:31 Debug:test:193
2018/12/19 10:48:56:358 ViewController.m:-[ViewController test]_block_invoke:31 Debug:test:194
2018/12/19 10:48:57:363 ViewController.m:-[ViewController test]_block_invoke:31 Debug:test:195
2018/12/19 10:48:58:369 ViewController.m:-[ViewController test]_block_invoke:31 Debug:test:196
2018/12/19 10:48:59:374 ViewController.m:-[ViewController test]_block_invoke:31 Debug:test:197
2018/12/19 10:49:00:380 ViewController.m:-[ViewController test]_block_invoke:31 Debug:test:198
2018/12/19 10:49:01:384 ViewController.m:-[ViewController test]_block_invoke:31 Debug:test:199
2018/12/19 10:49:02:390 ViewController.m:-[ViewController test]_block_invoke:31 Debug:test:200
-(void)test
{
FLDDLogDebug(@"測試加入GCD的MainDispatchQueue隊列線程在背景仍舊可以運作");
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for(NSInteger i = 0; ; i++)
{
sleep(1);
FLDDLogDebug(@"test:%ld", (long)i);
}
});
}