Swift4中如何创建串行队列?DispatchQueue.init参数写法咨询
在Swift 4中创建串行队列 & DispatchQueue初始化参数详解
嘿,我刚接触GCD的时候也对着那个满是参数的初始化方法头大过,别着急,我一步步给你讲清楚Swift 4里怎么创建串行队列,还有每个参数该怎么填~
一、快速创建串行队列的几种方式
其实创建串行队列很简单,GCD里的队列默认就是串行的,只要你不指定并行属性就行:
1. 最基础的写法
这是日常开发里用得最多的,只需要给队列加个唯一标识(label):
// 基础串行队列 let serialQueue = DispatchQueue(label: "com.yourdomain.yourapp.serial-task-queue")
2. 明确指定串行的写法(可选)
如果你想让代码更清晰,也可以显式指定attributes为空数组(因为.concurrent是并行队列的标志,不传这个就是串行):
// 明确标记为串行的队列(和上面效果完全一致) let explicitSerialQueue = DispatchQueue(label: "com.yourdomain.yourapp.explicit-serial", attributes: [])
二、DispatchQueue完整初始化参数全解析
你提到的这个带多个参数的初始化方法,每个参数都有明确的作用,我逐个给你拆解:
DispatchQueue.init( label: String, qos: DispatchQoS = .unspecified, attributes: DispatchQueue.Attributes = [], autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency = .inherit, target: DispatchQueue? = nil )
1. label: String
- 这是队列的唯一标识符,必须填写,推荐用反向域名格式(比如
com.yourapp.profile.loading-queue),这样在Xcode的调试导航器、Instruments里能快速找到对应的队列,排查卡顿或死锁问题时特别有用。 - 绝对不能传空字符串,得给个有意义的名字,方便后期维护。
2. qos: DispatchQoS
- 全称Quality of Service(服务质量),用来告诉系统这个队列的任务优先级,系统会根据它分配CPU资源。常用的取值有:
.userInteractive:最高优先级,用于和用户实时交互的操作(比如UI动画、按钮点击响应).userInitiated:次高优先级,用户主动触发的后台任务(比如加载用户刚点击的详情页数据).default:默认优先级,没指定qos时自动使用.utility:中等偏下,用户不需要立刻看到结果的任务(比如下载大文件、批量计算).background:最低优先级,完全后台的静默任务(比如日志上传、夜间数据同步).unspecified:不指定优先级,会继承目标队列(如果target参数有值)的qos
- 示例:给串行队列设置用户发起的优先级
let userInitiatedSerial = DispatchQueue(label: "com.yourapp.user-initiated", qos: .userInitiated)
3. attributes: DispatchQueue.Attributes
- 这是区分串行/并行队列的核心参数!
- 如果传
.concurrent,队列就是并行的;如果传空数组[]或者省略这个参数(默认就是空),队列就是串行的。 - 还有个可选值
.initiallyInactive:队列创建后不会自动激活,需要手动调用queue.activate()才能让任务执行,适合需要精准控制启动时机的场景。
- 如果传
- 所以要创建串行队列,这里只要不传
.concurrent就可以了。
4. autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency
- 控制自动释放池的创建频率,用来管理内存:
.inherit:继承目标队列的释放频率(如果target有值),否则默认和.workItem一致.workItem:每个任务执行完毕后,自动释放池会被清空,适合内存敏感的场景.never:队列不自动创建释放池,需要你在任务里手动管理释放池
- 日常开发用默认的
.inherit就足够了,除非你有特殊的内存优化需求。
5. target: DispatchQueue?
- 指定当前队列的“目标队列”,当前队列的所有任务都会被转发到目标队列去执行。
- 可以用来让多个队列共享同一个底层队列,或者间接调整队列优先级(不过更推荐直接设置
qos)。 - 一般不需要传这个参数,默认
nil,系统会自动分配合适的底层队列。
三、完整示例:带所有参数的串行队列
最后给你一个完整的示例,把所有参数都填上,你可以直接参考:
// 完整参数的串行队列 let fullConfigSerialQueue = DispatchQueue( label: "com.yourapp.full-config-serial", qos: .userInitiated, attributes: [], // 明确串行 autoreleaseFrequency: .workItem, target: nil ) // 测试串行执行 fullConfigSerialQueue.async { print("任务1启动") Thread.sleep(forTimeInterval: 1) // 模拟耗时操作 print("任务1完成") } fullConfigSerialQueue.async { print("任务2启动") Thread.sleep(forTimeInterval: 1) print("任务2完成") } // 输出顺序:任务1启动 → 任务1完成 → 任务2启动 → 任务2完成,证明是串行执行
内容的提问来源于stack exchange,提问作者J.Doe
相关产品推荐
相关产品推荐

