iOS开发多线程(GCD)

相关概念

  • 队列:用于储存任务
  • 线程:处理任务的单元
  • 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]);
    });
}
  • 小结
    1. 主线程(UI)线程可以执行其他队列的任务,但是主队列任务只会在主线程中执行。
    2. {}之中的代码在runloop看来都是一次任务
    3. 串行队列不是栈逻辑,而是先进先出。
    4. 前面代码分析了在主线程中开启处理新任务的情况,在此基础上可以分析出子线程的相应情况。

分析(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 *)touches withEvent:(UIEvent *)event {
    [self dismissViewControllerAnimated:YES completion:nil];
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
  • 此段小结
    1. dispatch_source_cancel()可以取消block任务;
    2. dispatch_source_t是ARC管理的(当控制器销毁时,定时器block任务被取消);

你可能感兴趣的:(iOS开发多线程(GCD))