首页 iOS.& Swift Books 通过教程并发

6
运营 由Scott Grosch撰写

现在你是一个忍者大师的大中央派遣,是时候转移齿轮并看看 运营。在某些方面,操作行为非常像GCD,当您首次开始使用并发时,它可能会令人困惑。

GCD和操作都允许您提交一个块的代码,该块应该在单独的线程上运行;但是,操作允许更好地控制提交的任务。

如图开始于本书的开始,操作内置于GCD之上。它们添加了额外的功能,如依赖性的其他操作,能够取消运行操作,以及面向对象模型,以支持更复杂的要求。

可重用性

One of the first reasons you’ll likely want to create an Operation is for reusability. If you’ve got a simple “fire and forget” task, then GCD is likely all you’ll need.

An Operation is an actual Swift object, meaning you can pass inputs to set up the task, implement helper methods, etc. Thus, you can wrap up a unit of work, or task, and execute it sometime in the future, and then easily submit that unit of work more than once.

行动状态

操作具有表示其生命周期的状态机。在此生命周期的各个部分存在有几种可能的状态:

障碍物

You can quickly create an Operation out of a block of code using the 障碍物 class. Normally, you would simply pass a closure to its initializer:

let operation = BlockOperation {
  print("2 + 3 = \(2 + 3)")
}

多个块操作

在本章的入门材料中,您会发现一个名叫的操场 blockoperation.playground.. This playground provides a default duration function for timing your code, which you’ll use in a moment.

let sentence = "Ray’s courses are the best!"
let wordOperation = BlockOperation()

for word in sentence.split(separator: " ") {
  wordOperation.addExecutionBlock {
    print(word)
  }
}

wordOperation.start()

sleep(2)
duration {
  wordOperation.start()
}

wordOperation.completionBlock = {
  print("Thank you for your patronage!")
}

子类操作

The 障碍物 class is great for simple tasks but if performing more complex work, or for reusable components, you’ll want to subclass Operation yourself.

倾斜换下错误的方式

由于尤达大师,“最伟大的老师,失败是”,你将首先实现倾斜移位大多数首次定时器的天真的方式。

let name = "\(indexPath.row).png"
let inputImage = UIImage(named: name)!
print("Tilt shifting image \(name)")

guard let filter = TiltShiftFilter(image: inputImage, radius: 3),
      let output = filter.outputImage else {
  print("Failed to generate tilt shift image")
  cell.display(image: nil)
  return cell
}
print("Generating UIImage for \(name)")
let fromRect = CGRect(origin: .zero, size: inputImage.size)
guard let cgImage = context.createCGImage(output, from: fromRect) else {
  print("No image generated")
  cell.display(image: nil)
  return cell
}

cell.display(image: UIImage(cgImage: cgImage))

print("Displaying \(name)")

倾斜转移几乎正确

It should come as no surprise that the Core Image operations should be placed into an Operation subclass at this point. You’re going to need both an input and an output image, so you’ll create those two properties. The input image should never change so it makes sense to pass it to the initializer and make it private.

import UIKit

final class TiltShiftOperation: Operation {
  var outputImage: UIImage?

  private let inputImage: UIImage

  init(image: UIImage) {
    inputImage = image
    super.init()
  }
}
private static let context = CIContext()
override func main() {
  guard let filter = TiltShiftFilter(image: inputImage, radius: 3),
        let output = filter.outputImage else {
    print("Failed to generate tilt shift image")
    return
  }

  let fromRect = CGRect(origin: .zero, size: inputImage.size)
  guard let cgImage = TiltShiftOperation
                          .context
                          .createCGImage(output, from: fromRect) else {
    print("No image generated")
    return
  }

  outputImage = UIImage(cgImage: cgImage)
}
override func tableView(
  _ tableView: UITableView, 
  cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  
  let cell = tableView.dequeueReusableCell(withIdentifier: "normal",
                                           for: indexPath) as! PhotoCell

  let image = UIImage(named: "\(indexPath.row).png")!

  print("Filtering")
  let op = TiltShiftOperation(image: image)
  op.start()

  cell.display(image: op.outputImage)
  print("Done")
  
  return cell
}

有一个技术问题?想报告一个错误吗? 您可以向官方书籍论坛中的书籍作者提出问题和报告错误 这里.

有反馈分享在线阅读体验吗? 如果您有关于UI,UX,突出显示或我们在线阅读器的其他功能的反馈,您可以将其发送到设计团队,其中表格如下所示:

© 2021 Razeware LLC

您可以免费读取,本章的部分显示为 混淆了 文本。解锁这本书,以及我们整个书籍和视频目录,带有Raywenderlich.com的专业订阅。

现在解锁

要突出或记笔记,您需要在订阅中拥有这本书或自行购买。