NSObject
1 - NSObject:它存在着了一个最简单的后台执行方法
- (void)performSelectorInBackground:(SEL)aSelector withObject:(nullable id)arg
GCD
1 - GCD:以队列的方式进行工作,它有两种队列
① SerialQueue:一次只执行一个任务,它通常用于同步访问特定的资源或数据
当你创建多个 Serial queue 时,虽然它们各自内部是同步进行的,但 Serial queue 与 Serial queue 之间是并发执行的
② Concurrent:可以并发的执行多个任务,遵循 FIFO
线程之间的通信,分为两种:主线程进入子线程(上述的四种方法均可以);子线程进入主线程
2 - GCD 常用 API
1 dispatch_once() // 往队列中添加任务,任务只执行一次 2 dispatch_sync() // 往队列中添加任务,block 不执行完,下面的代码不会执行 3 dispatch_async_f()// 往队列中添加任务,任务时函数非 block 4 5 dispatch_async() // 往队列中添加任务,任务会排队执行 6 dispatch_after() // 往队列中添加任务,任务不但会排队,而且会在延迟到的时间点执行 7 dispatch_apply() // 往队列中添加任务,任务会重复执行 n 次 8 9 dispatch_group_async() // 将任务添加到队列中,并添加分组标记 10 dispatch_group_notify() // 将任务添加到队列中,当某个分组的所有任务执行完毕后,此任务才会执行 11 dispatch_barrier_async()// 将任务添加到队列中,此任务执行的时候,其它任务停止执行
3 - 代码示例
① GCD 基本应用
1 // 主队列是一个单例,意味着在不同地方获取均为同一个,执行方式串行,任务都是运行在主线程 2 dispatch_queue_t mainQueue = dispatch_get_main_queue(); 3 NSLog(@"%@",mainQueue); 4 5 // 全局队列:并发执行,任务都是运行在子线程 6 // 根据优先级的不同对应 4 个单例 7 dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 8 NSLog(@"%@",globalQueue); 9 10 // 自定义队列:任务运行在子线程,任务的执行可以指定是串行还是并发 11 // 并发 - DISPATCH_QUEUE_CONCURRENT; 串行 - DISPATCH_QUEUE_SERIAL 12 dispatch_queue_t customQueue = dispatch_queue_create("HelloGCD", DISPATCH_QUEUE_CONCURRENT); 13 NSLog(@"%@",customQueue); 14 15 16 // dispatch_sync:必须等待 block 执行完,才会往下执行。如果是同步且又往主线程提交任务,会导致 UI 直接假死 17 // dispatch_async:不须等待 block 执行完,就会往下执行; 18 // 异步调度队列的优先级并不是指先执行完优先级高的后再去执行优先级低的 19 // 而是并发执行,只是优先并发优先级高的队列(高概率) 20 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 21 22 // 优先级 DEFAULT 23 [self crazyText];// 疯狂输出,造成阻塞 24 // 回到主线程刷新 UI 25 [self performSelectorOnMainThread:@selector(updateUI) withObject:self waitUntilDone:YES]; 26 }); 27 28 // 验证:不须等待 block 执行完就执行该行代码 29 NSLog(@"hello Block,dispatch_async"); 30 31 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 32 33 // 优先级高:与默认的队列并发执行 34 [self crazyText]; 35 });
1 -(void)crazyText{ 2 3 for (int i = 3500; i > 3000; i--) { 4 5 NSString * str = [NSString stringWithFormat:@"i = %d",i]; 6 NSLog(@"%@", str); 7 } 8 9 } 10 11 // 更新 UI... 12 - (void)updateUI{ 13 14 self.view.backgroundColor = [UIColor redColor]; 15 }
② dispatch_group_t
1 // 创建一个任务组 2 dispatch_group_t taskGroup = dispatch_group_create(); 3 // 任务1 4 dispatch_group_async(taskGroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 5 for (int i = 0; i < 400; i ++) { 6 NSLog(@"-----i = %d",i); 7 } 8 }); 9 10 // 任务2 11 dispatch_group_async(taskGroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 12 for (int j = 800; j>400; j --) { 13 NSLog(@">>>>>j = %d",j); 14 } 15 }); 16 17 // 任务3 18 dispatch_group_async(taskGroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 19 for (int k = 1000; k<1400; k ++) { 20 NSLog(@"<<<<<k = %d",k); 21 } 22 }); 23 24 // 任务组通知:当多个任务捆绑到一起的时候,待任务全部执行完毕以后,会收到通知; 25 dispatch_group_notify(taskGroup, dispatch_get_main_queue(), ^{ 26 NSLog(@"三个任务已经行完毕"); 27 });
③ 其它用法
1 // GCD 延迟多长时间调用(3.0s) 2 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 3 NSLog(@"dispatch_after");// 10秒后打印 4 }); 5 6 // 往队列里边多次提交同一任务(这里是3次) 7 dispatch_apply(3, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t n) { 8 for (int i = 0; i < 10; i ++) { 9 NSLog(@"第%ld次,i = %d",n,i); 10 } 11 });