iOS中的多线程与GCD队列关系

请添加图片描述

1、iOS中的常见多线程方案

在这里插入图片描述

2、GCD与队列

2.1、常用函数

GCD中有2个用来执行任务的函数
1、用同步的方式执行任务

/**
* @param: queue:队列
* @param: block:任务
*/
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);

2、用异步的方式执行任务

dispatch_async(dispatch_queue_t queue, dispatch_block_t block);

GCD源码https://github.com/apple/swift-corelibs-libdispatch

2.2、queue队列

1、并发队列(Concurrent Dispatch Queue)

1、可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)
2、并发功能只有在异步(dispatch_async)函数下才有效

2、串行队列(Serial Dispatch Queue)

让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)

2.3、同步、异步、并发、串行

1、同步和异步主要影响:能不能开启新的线程

1、同步:在当前线程中执行任务,不具备开启新线程的能力
2、异步:在新的线程中执行任务,具备开启新线程的能力

2、并发和串行主要影响:任务的执行方式

1、并发:多个任务并发(同时)执行
2、串行:一个任务执行完毕后,再执行下一个任务

2.4、各种队列的执行效果

在这里插入图片描述
注意:使用sync函数往当前串行队列中添加任务,会卡住当前的串行队列(产生死锁)。

2.5、队列组的使用

思考:如何用GCD实现以下功能
1、异步并发执行任务1、任务2
2、等任务1、任务2都执行完毕后,再回到主线程执行任务3
在这里插入图片描述

3、问答拓展

1、你理解的多线程?
2、iOS的多线程方案有哪几种?你更倾向于哪一种?
3、你在项目中用过 GCD 吗?
4、GCD 的队列类型
5、说一下 OperationQueue 和 GCD 的区别,以及各自的优势。

6、请问下面代码的打印结果是什么?
在这里插入图片描述

1、打印结果是:1、3
2、原因:

1、performSelector:withObject:afterDelay:的本质是往Runloop中添加定时器。
2、子线程默认没有启动Runloop。

3、解决方案见如下代码:

- (void)test2 {
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    dispatch_async(queue, ^{
        NSLog(@"1");
        // 这句代码的本质是往Runloop中添加定时器
        [self performSelector:@selector(test) withObject:nil afterDelay:.0];
        NSLog(@"3");
        // 获取runloop,并运行runloop
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    });
}

- (void)test {
    NSLog(@"2");
}

7、请问下面代码的打印结果是什么?
在这里插入图片描述

打印结果是:1
原因:
1、thread子线程执行完毕之后,由于没有runloop执行,所以函数执行完即销毁。
2、当performSelector:…调用thread子线程时,此时子线程已经被销毁,所以会报错。
3、解决方案:线程保活。见下面代码

- (void)test {
    NSLog(@"2");
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSThread *thread = [[NSThread alloc] initWithBlock:^{
        NSLog(@"1");
        
        [[NSRunLoop currentRunLoop] addPort:[[NSPort alloc] init] forMode:NSDefaultRunLoopMode];
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    }];
    [thread start];
    
    [self performSelector:@selector(test) onThread:thread withObject:nil waitUntilDone:YES];
}

**🏆结语🏆 **
💖如果觉得这篇文章对您有点帮助的话,请点赞👍+收藏⭐️+留言📝支持一下博主哦🤞

  • 18
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 20
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瓜子三百克

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值