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

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

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


606403c4a97a40f7b825069a7ebd78cf.png

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、各种队列的执行效果

3b1e97e372e74f32864dfa341735a957.png

注意:使用sync函数往当前串行队列中添加任务,会卡住当前的串行队列(产生死锁)。


2.5、队列组的使用

思考:如何用GCD实现以下功能

1、异步并发执行任务1、任务2

2、等任务1、任务2都执行完毕后,再回到主线程执行任务3

e1ccc3c9e7c74b9b80873d1425f57238.png


3、问答拓展


1、你理解的多线程?

2、iOS的多线程方案有哪几种?你更倾向于哪一种?

3、你在项目中用过 GCD 吗?

4、GCD 的队列类型

5、说一下 OperationQueue 和 GCD 的区别,以及各自的优势。


6、请问下面代码的打印结果是什么?

1e0c910aaff74b21a61fd323a3ecb1b7.png


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、请问下面代码的打印结果是什么?

d34e8b50153d471c9d0de4923e220f17.png


打印结果是: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];
相关文章
|
19天前
|
缓存 安全 C++
C++无锁队列:解锁多线程编程新境界
【10月更文挑战第27天】
33 7
|
19天前
|
消息中间件 存储 安全
|
1月前
|
存储 运维 API
源码解密协程队列和线程队列的实现原理(一)
源码解密协程队列和线程队列的实现原理(一)
35 1
|
1月前
|
存储 安全 API
源码解密协程队列和线程队列的实现原理(二)
源码解密协程队列和线程队列的实现原理(二)
33 1
|
1月前
|
安全 调度 数据安全/隐私保护
iOS线程锁
iOS线程锁
27 0
|
2月前
|
API Android开发 iOS开发
安卓与iOS开发中的线程管理对比
【9月更文挑战第12天】在移动应用的世界中,安卓和iOS平台各自拥有庞大的用户群体。开发者们在这两个平台上构建应用时,线程管理是他们必须面对的关键挑战之一。本文将深入探讨两大平台在线程管理方面的异同,通过直观的代码示例,揭示它们各自的设计理念和实现方式,帮助读者更好地理解如何在安卓与iOS开发中高效地处理多线程任务。
|
3月前
|
存储 监控 Java
|
3月前
|
安全 测试技术 调度
iOS开发-多线程编程
【8月更文挑战第12天】在iOS开发中,属性的内存管理至关重要,直接影响应用性能与稳定性。主要策略包括:`strong`(强引用),保持对象不被释放;`weak`(弱引用),不保持对象,有助于避免循环引用;`assign`(赋值),适用于基本数据类型及非指针对象类型;`copy`(复制),复制对象而非引用,确保不变性。内存管理基于引用计数,利用自动引用计数(ARC)自动管理对象生命周期。此外,需注意避免循环引用,特别是在block中。最佳实践包括理解各策略、避免不必要的强引用、及时释放不再使用的对象、注意block中的内存管理,并使用工具进行内存分析。正确管理内存能显著提升应用质量。
|
3月前
|
API Swift C语言
探索iOS开发:Swift中的异步编程与GCD应用
【8月更文挑战第4天】在iOS开发的海洋中,掌握Swift语言的航向是至关重要的。本文将引领你深入理解Swift中的异步编程概念,并借助Grand Central Dispatch(GCD)这一强大的工具,来简化并发编程的复杂性。我们将通过实际代码示例,展现如何在iOS应用中高效地管理后台任务和提升用户界面的响应性。
78 3
|
3月前
|
安全 网络安全 数据安全/隐私保护
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享安卓与iOS开发中的线程管理比较
【8月更文挑战第30天】本文将探讨网络安全与信息安全的重要性,并分享关于网络安全漏洞、加密技术和安全意识的知识。我们将了解常见的网络攻击类型和防御策略,以及如何通过加密技术和提高安全意识来保护个人和组织的信息安全。