相关概念
- 队列:用于储存任务
- 线程:处理任务的单元
- sync:同步处理(立即处理)
- async:异步处理(稍后处理或者开启其他线程处理)
- dispatch_source_t:定时器(资源)
分析(线程任务)
- 主线程中同步处理主队列任务
结果会是死锁:原因是同一线程不能跳步执行串行队列(主队列是串行队列)任务。
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"____");
});
- 主线程中异步处理主队列任务
结果会按照以下log顺序:异步意味着不立即执行新任务,但是任务在主队列中(主队列任务只能在主线程执行)。
NSLog(@"-----1");
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"-----3");
});
sleep(3);
NSLog(@"-----2");
- 主线程中异步处理全局队列任务(全局队列属于并发队列)
结果会按照以下log顺序:异步意味着不立即执行新任务,但是可以分配给其他线程执行(几乎立刻)。
NSLog(@"-----1");
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"-----2");// 子线程
});
sleep(3);
NSLog(@"-----3");
- 主线程中同步处理全局队列任务(全局队列属于并发队列)
结果会按照以下log顺序:同步意味着立即执行新任务,暂停当前队列的当前任务。
NSLog(@"-----1");
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"-----2");//主线程
});
NSLog(@"-----3");
sleep(3);
NSLog(@"-----4");
- 主线程异步串行队列任务,然后在线程3(子线程)中同步本串行队列任务出现死锁。
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, ^{ // 发生死锁
NSLog(@"currentThread,%@", [NSThread currentThread]);
});
}
- 小结
- 主线程(UI)线程可以执行其他队列的任务,但是主队列任务只会在主线程中执行。
- {}之中的代码在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); //每秒执行
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任务被取消);