30 行代码实现一个 GCD 线程池(简单)

3,542 阅读1分钟

首发于公众号

开发的时候,有时候需要限制任务的最大并发数,比如显示弹幕、上传或者下载文件,但是系统的库里面没有提供类似线程池的工具。

苹果推荐使用 GCD 的方法来创建线程,因为 GCD 使用简单而且不需要手动管理线程释放。

那就基于 GCD 来实现一个线程池吧,当然使用上越简单越好,使用者不需要关心线程的数量,只管往线程里添加任务就行了。

这个库的名字叫 SFDispatchQueuePool。

比如要发 1000 条弹幕,屏幕上每次最多显示 10 条,那么只要限制线程池的最大并发数目是 10 个就行了,用法如下:

let sharedPool = SFDispatchQueuePool.pool()

for i in 0...1000 {
  sharedPool.async {
    // 在这里执行任务
    ...
  }
}

如果执行的任务是异步的呢?比如 URLSession 就是异步执行的。

也可以支持,很简单,只需要把异步变成同步就行了。

sharedPool.async {
  let lock = DispatchSemaphore(value: 0)
  let task = URLSession.shared.dataTask(with: URL(string: "https://github.com")!) {data, response, error in
               lock.signal()
             }
  
  task.resume()
  lock.wait()
}

通过信号量等待网络请求,让异步变成同步。

SFDispatchQueuePool 的代码只有 30 行。

github.com/cntrump/SFD…