相關概念
- 隊列:用于儲存任務
- 線程:處理任務的單元
- sync:同步處理(立即處理)
- async:異步處理(稍后處理或者開啟其他線程處理)
- dispatch_source_t:定時器(資源)
分析(線程任務)
- 主線程中同步處理主隊列任務
結果會是死鎖:原因是同一線程不能跳步執(zhí)行串行隊列(主隊列是串行隊列)任務淮捆。
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"____");
});
- 主線程中異步處理主隊列任務
結果會按照以下log順序:異步意味著不立即執(zhí)行新任務辕羽,但是任務在主隊列中(主隊列任務只能在主線程執(zhí)行)会喝。
NSLog(@"-----1");
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"-----3");
});
sleep(3);
NSLog(@"-----2");
- 主線程中異步處理全局隊列任務(全局隊列屬于并發(fā)隊列)
結果會按照以下log順序:異步意味著不立即執(zhí)行新任務空闲,但是可以分配給其他線程執(zhí)行(幾乎立刻)催跪。
NSLog(@"-----1");
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"-----2");// 子線程
});
sleep(3);
NSLog(@"-----3");
- 主線程中同步處理全局隊列任務(全局隊列屬于并發(fā)隊列)
結果會按照以下log順序:同步意味著立即執(zhí)行新任務投蝉,暫停當前隊列的當前任務裙士。
NSLog(@"-----1");
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"-----2");//主線程
});
NSLog(@"-----3");
sleep(3);
NSLog(@"-----4");
- 主線程異步串行隊列任務膊爪,然后在線程3(子線程)中同步本串行隊列任務出現(xiàn)死鎖自阱。
dispatch_queue_t dispatchQueue = dispatch_queue_create("xin.queue", DISPATCH_QUEUE_SERIAL);
dispatch_async(dispatchQueue, ^{
NSLog(@"currentThread,%@", [NSThread currentThread]); // 線程3
[self openNewActionWithQue:dispatchQueue];
});
- (void)openNewActionWithQue:(dispatch_queue_t)queue {
NSLog(@"currentThread,%@", [NSThread currentThread]);線程3
dispatch_sync(queue, ^{ // 發(fā)生死鎖
NSLog(@"currentThread,%@", [NSThread currentThread]);
});
}
- 小結
- 主線程(UI)線程可以執(zhí)行其他隊列的任務,但是主隊列任務只會在主線程中執(zhí)行米酬。
- {}之中的代碼在runloop看來都是一次任務
- 串行隊列不是棧邏輯沛豌,而是先進先出。
- 前面代碼分析了在主線程中開啟處理新任務的情況赃额,在此基礎上可以分析出子線程的相應情況加派。
分析(dispatch_source_t)
看段代碼
#import "TestViewController.h"
@interface TestViewController ()
@property(nonatomic,strong) dispatch_source_t timer;
@end
@implementation TestViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
__block NSInteger timeout = 10;//倒計總時間
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
__weak typeof(_timer) timer2 = _timer;
dispatch_source_set_timer(timer2,dispatch_walltime(NULL, 0),1*NSEC_PER_SEC, 0); //每秒執(zhí)行
dispatch_source_set_event_handler(timer2, ^{
NSLog(@"%s",__func__);
if(timeout<=0){ //倒計時結束,關閉
dispatch_source_cancel(timer2);
} else {
dispatch_async(dispatch_get_main_queue(), ^{
});
timeout-=1;
}
});
dispatch_resume(_timer);
}
- (void)dealloc {
NSLog(@"%s",__func__);
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- 此段小結
- dispatch_source_cancel()可以取消block任務跳芳;
- dispatch_source_t是ARC管理的(當控制器銷毀時芍锦,定時器block任務被取消);