iOS 多线程 GCD(日常开发中使用频度最多的多线程技术方案)
2023-09-14 09:04:14 时间
文章目录
0.我的另外一篇博客
1.简介
2.同步串行
2.1 死锁
- 队列引起的循环等待,而不是线程引起的循环等待
- viewDidLoad执行过程中需要调用Block, Block完成后viewDidLoad方法才能继续向下走;viewDidLoad方法的结束需要依赖于后面提交的Block任务。Block任务要想执行需要等到viewDidLoad执行完成。循环等待
- 同步提交,意味着在当前线程执行
3.同步并发
- 今日头条
- global_queue: 并发队列,并发队列中的任务可以并发执行
- global_queue改为串行队列会发生死锁
4.异步串行
5.异步并发
- 腾讯视频面试真题
- GCD底层的线程默认是没有开启runloop的
- performSelector方法会提交到当前线程的runloop
- 我自己的测试
PerformSelector 和多线程的关系_sinat_32283541的博客-CSDN博客
iOS performSelector 实现原理 - 云+社区 - 腾讯云
6.dispatch_barrier_async():多读单写
苹果官方文档:dispatch_barrier_async
这个博客示例了dispatch_barrier_async:
dispatch_barrier_async 与 dispatch_barrier_sync区别
6.1 什么是多读单写
- 滴滴公司和美团公司的面试题
- 栅栏异步调用
6.2 代码实现
//
// UserCenter.m
// GCD
//
// Created by yangyang38 on 2018/3/16.
// Copyright © 2018年 yangyang. All rights reserved.
//
#import "UserCenter.h"
@interface UserCenter()
{
// 定义一个并发队列
dispatch_queue_t concurrent_queue;
// 用户数据中心, 可能多个线程需要数据访问
NSMutableDictionary *userCenterDic;
}
@end
// 多读单写模型
@implementation UserCenter
- (id)init
{
self = [super init];
if (self) {
// 通过宏定义 DISPATCH_QUEUE_CONCURRENT 创建一个并发队列
concurrent_queue = dispatch_queue_create("read_write_queue", DISPATCH_QUEUE_CONCURRENT);
// 创建数据容器
userCenterDic = [NSMutableDictionary dictionary];
}
return self;
}
- (id)objectForKey:(NSString *)key
{
__block id obj;
// 同步读取指定数据 同步方式可以立刻返回数据 并发队列多个读取操作可以并发执行
//获取操作是要有立刻同步返回结果的,所以用_sync。 同步到并发队列中,就可以有多个线程同时读
dispatch_sync(concurrent_queue, ^{
obj = [userCenterDic objectForKey:key];
});
return obj;
}
- (void)setObject:(id)obj forKey:(NSString *)key
{
// 异步栅栏调用设置数据
dispatch_barrier_async(concurrent_queue, ^{
[userCenterDic setObject:obj forKey:key];
});
}
@end
6.3 我自己的测试示例
7.dispatch_group_async()
- A,B,C中不开启新线程,结论才成立。A,B,C中代码都从头到尾执行完后会执行D。如果A中又开启新线程去下载图片(不会阻塞A的线程),那么当图片下载完回来,D可能已经执行完了.这是本人在项目中遇到要上传完多张图片后再执行任务,本来想用dispatch_group_async,结果发现不行,因为在下载图片是会异步开启新线程
- 爱奇艺真题
7.2 代码实现
//
// GroupObject.m
// GCD
//
// Created by yangyang38 on 2018/3/16.
// Copyright © 2018年 yangyang. All rights reserved.
//
#import "GroupObject.h"
@interface GroupObject()
{
dispatch_queue_t concurrent_queue;
NSMutableArray <NSURL *> *arrayURLs;
}
@end
@implementation GroupObject
- (id)init
{
self = [super init];
if (self) {
// 创建并发队列
concurrent_queue = dispatch_queue_create("concurrent_queue", DISPATCH_QUEUE_CONCURRENT);
arrayURLs = [NSMutableArray array];
}
return self;
}
- (void)handle
{
// 创建一个group
dispatch_group_t group = dispatch_group_create();
// for循环遍历各个元素执行操作
for (NSURL *url in arrayURLs) {
// 异步组分派到并发队列当中
dispatch_group_async(group, concurrent_queue, ^{
//根据url去下载图片
NSLog(@"url is %@", url);
});
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 当添加到组中的所有任务执行完成之后会调用该Block
NSLog(@"所有图片已全部下载完成");
});
}
@end
7.3 我自己的测试例子
- d2会在d1后执行,在target后执行
8.gcd也有挂起和取消:queue.suspend() dispatchWorkItem.cancel()
- 默认创建的是串行队列
相关文章
- (NO.00001)iOS游戏SpeedBoy Lite成形记(十八)
- unity3d 安卓IOS推送
- iOS Xcode编译文件存在却说找不到
- iOS 画出不规则图形
- iOS开发UI篇—使用UItableview完成一个简单的QQ好友列表(一)
- IOS常用加密DES
- mac ---Charles抓包---ios苹果手机
- 《iPhone与iPad开发实战—iOS经典应用剖析》连载七
- ios UI适配 主要机型的尺寸 物理点pt 和 分辨率px
- iOS swift5 改变UILabel上指定文字的颜色和字体
- iOS swift 位置 定位 获取海拔
- ios swift5 MJRefresh 隐藏MJRefreshHeader
- iOS 多线程 swift5 GCD 自己消化的
- iOS 多线程面试问题总结
- iOS RunLoop与NSTimer RunLoop与多线程
- iOS多线程:GCD详解
- 【iOS】多线程GCD