斯坦福公开课Swift笔记 10:多线程GCD(MultiThr

2020-07-27  本文已影响0人  CyberDunk1997

1. 队列

2. 主队列

3. 全局队列

4. iOS中如何获得队列?

4.1 获得一个队列

//1. 获得一个主队列
let mainQueue = DispatchQueue.main
//2. 获得全局,并发,在后台运行的队列
let backgroudQueue = DispatchQueue.global(qos : DispatchQos)

DispatchQueue.userInteractive // 高优先级,适合又短又快的任务,很少用,可以在主线程上做
DispatchQueue.userInitiated // 高优先级,适合有一点耗时的任务,比较常用
DispatchQueue.backgroud // 低优先级,不直接被用户创建,所以可以做很耗时的任务
DispatchQueue.utility // 低优先级,长时间的后台处理

4.2 在队列中添加代码

  1. 异步执行:保持当前队列运行,并在另一条队列中添加任务
  queue.async { ... }
  1. 同步执行:阻止当前队列运行,等待加入队列中的任务完成后再继续执行
  queue.sync { ... }

4.3 创建你自己的队列

//创建一个自己的串行队列
let serialQueue = DispatchQueue(label: "MySerialQ")
//创建一个自己的并行队列
let concurrentQueue = DispatchQueue(label: "MyConcurrentQ", attributes: .concurrent)

4.4 OperationQueue 和 Operation

4.5 iOS API中的多线程

let session = URLSession(configuration: .default)
if let url = URL(string: "http://www.baidu.com") {
  let task = session.dataTask(with:url) { (data: Data? , response , error ) in 
  // **在这里能用下载的data来更新我的UI界面的吗?**
  xxx...
  }
  task.resume()
}
let session = URLSession(configuration: .default)
if let url = URL(string: "http://www.baidu.com") {
  let task = session.dataTask(with:url) { (data: Data? , response , error ) in 
    Dispatch.main.async {
      // 这里可以更新UI啦!
    }
  }
  task.resume()
}

4.6 异步执行顺序

异步执行顺序.png
  1. 第一步:a。将String转换成url。
  2. 第二步:b。这一行代码除了创建了一个dataTask并把它传给task之外什么也没做,b行被执行后会立即返回,等待数据下载完成后才执行闭包里的代码。
  3. 第三步:g。g做的是在其他队列中获取数据。g行在b行后会被立即执行,也同时会立即返回。
  4. 第四步:h。打印“已经发起了url请求”。这时已经跳出了第一个大括号。a→b→g→h被执行,它们是一个接一个地被执行,中间没有任何停顿,而c,d,e,f行会在其他另一个队列中被执行。
  5. 第五步:c。在几秒钟,或者是几分钟,甚至时几小时后,数据终于返回,c行被执行,在这里可以进行处理数据
  6. 第六步:d。在这里发起返回主队列的异步请求。由于主队列可能正在进行其他任务,所以不一定会立即响应,e不会被立即执行。
  7. 第七步:f。打印“做一些处理data数据的工作,但此时UI还没有更新”。
  8. 第八步:e。等待主队列没有任务在执行了,终于轮到e执行,可以更新UI了。

请求图片的实例代码

if let url = imageURL { // 获取一个url地址
  DispatchQueue.global(qos: .userInitiated).async { //在全局并发线程中,发起一个异步请求
  let urlContents = try ? Data(contentsOf: url) //用url地址去发起请求,将返回结果赋值给urlContents
  if let imageData = urlContents { // 如果返回的内容非空...,赋值给imageData 
    self.image = UIImage(data: imageData) //给self.image赋值
    }
  }
}
if let url = imageURL {
  DispatchQueue.global(qos: .userInitiated).async { *** [ weak self ]  in *** //注意这里
  let urlContents = try ? Data(contentsOf: url)
  if let imageData = urlContents { 
    self?.image = UIImage(data: imageData) //self.image 变成了self?.image, 当self不存在时,不执行
    }
  }
}
if let url = imageURL {
  DispatchQueue.global(qos: .userInitiated).async { *** [ weak self ]  in *** //注意这里
  let urlContents = try ? Data(contentsOf: url)
    DispatchQueue.main.async { //回到主队列
      if let imageData = urlContents ,url == self?.imageURL { //加一层判断,保证返回的数据是我所需要的
      self?.image = UIImage(data: imageData) //self.image 变成了self?.image, 当self不存在时,不执行
      }
    }
  }
}
上一篇 下一篇

猜你喜欢

热点阅读