/* Page prose (zh-Hans) */
"TakingOverTheStateMachine" = "# 接管状态机\n\n一个 `Operation` 会经过一个小小的**状态机**：`ready` → `executing` → `finished`。\n\n* **ready**：依赖已满足，等待轮到它。\n* **executing**：当前正在运行。\n* **finished**：完成了（无论它是正常完成还是被取消）。\n\n对于一个普通的操作，Foundation 会替你驱动这些转换，并在 `main()` 返回时立刻切换到 **finished**。对于基于回调的工作，你需要让操作停留在 **executing**，直到回调触发，所以你必须自己驱动这些转换。\n\nFoundation 使用 **KVO**（Key-Value Observing）监视三个只读属性（`isReady`、`isExecuting`、`isFinished`），KVO 是 Objective-C 的一种机制，一个对象通过它宣告“这个属性即将改变 / 刚刚改变”，好让观察者能够做出反应。`OperationQueue` 观察 `isFinished`；它就是这样得知一个操作已经完成，并能够启动下一个依赖它的操作。所以当你手动切换这些状态时，你必须**触发 KVO 通知**（之前用 `willChangeValue(forKey:)`，之后用 `didChangeValue(forKey:)`），否则队列永远不会知道。\n\n还有一个部分。你重写 `isAsynchronous` 让它返回 `true`。这是你对 Foundation 的承诺：*“别在 `start()` 返回时就假设我已经完成了；盯着 `isFinished`，我会自己切换它。”* 这是一个小巧、可复用的基类，它做的正是这件事：";
"TakingOverTheStateMachine-2" = "仔细读一读 `start()`。如果操作在开始之前就被取消了，我们不运行 `main()`，直接进入 **finished**。否则我们转到 **executing** 并调用 `main()`，但我们*不*在这里结束。操作会停留在 **executing**，直到有人调用 `finish()`，它把操作移到 **finished**，并触发队列正在等待的那个 KVO 通知。\n\n现在上传变得正确了。一个子类重写 `main()`，启动异步工作，并从回调里调用 `finish()`：";
"TakingOverTheStateMachine-3" = "**观察运行：**现在顺序是 `⬆️ Uploading...`，然后一秒之后是 `✅ ... reached the print server`，*只有到那时*才是 `🎉 completionBlock`。操作在整整那一秒里都停留在 **executing**，正如它应该的那样。如果这次上传有一个依赖它的操作，它现在会等待真正的完成，而不是过早的那次。\n\n* callout(试一试): 把回调里的 `self.finish()` 调用注释掉再运行：`🎉 completionBlock` 那一行永远不会出现，因为操作永远不会离开 **executing**。\n\n> **你不能打破的那一条规则：**一个异步操作必须*总是*到达 **finished**，在每一条路径上：成功*和*取消。这就是为什么上面的取消分支仍然调用 `finish()`。忘了它，操作就会永远卡在 **executing**，把队列堵在它后面，就像一次永远清不掉的卡纸。\n\n[上一页](@previous)  |  第 5 / 7 页  |  [下一页: completionBlock 简述](@next)";
