/* Page prose (zh-Hans) */
"WhereBugsHide" = "# 数一数 bug 能藏身的地方\n\n那个唯一的顺利路径的结果，掩盖了许多倒霉的可能。走一遍代码，把它们数出来：\n\n* **嵌套本身。**  \n三个步骤，三层缩进，而真正的逻辑（“装订成册”）位于最右边，最难找。这就是**厄运金字塔**：一种随着每一个相互依赖的步骤而横向生长的调用结构。\n* **三条分开的错误路径。**  \n每个 `.failure` 都得记着去调用 `completion(.failure(error))`。漏掉一个，那次失败就无声无息地消失了；调用方的 completion 干脆永远不会被调用。\n* **容易漏掉的 completion。**  \n没有任何编译器规则说“你必须在每一条路径上都调用 `completion`”。加上第四个分支，忘了那个回调，页面就会永远挂起，没有任何错误。\n* **对 `self` 的捕获。**  \n因为一个 handler 的存活时间比启动它的那个函数更长，强捕获 `self` 可能会让 `PrintShop` 比预期活得更久。我们写了 `[weak self]`，但*记着*要写、并且写对，都是手动的。\n* **跳回主线程。**  \n`bindBooklet` 是在一个后台队列上回报的。我们加上了 `DispatchQueue.main.async`，好让一次 UI 更新是安全的。忘了它，你就会得到一个只*偶尔*出问题的 bug，是最难追查的那一种。\n\n这些没有一个是稀奇古怪的。每一个都是基于闭包的代码库里再普通不过的一个周二。这个模型并没有*错*；它只是让正确性在每一处接缝上都成了*你的*责任。\n\n[上一页](@previous)  |  第 4 / 6 页  |  [下一页: 同样的任务，重写](@next)";
