对 weak 引用使用强制解包可能把正常生命周期变化变成应用崩溃
原文依据:3 处文档称 weak 引用在强所有者最后一次使用后变为 nil 是合法行为,却同时表示可选绑定比强制解包“更糟”。若代理据此把安全的 nil 处理改成 `!`,对象正常释放就会触发运行时陷阱。
受影响进程可能立即崩溃;如果该路径可由请求、界面事件或外部输入反复触发,会形成拒绝服务或数据未保存风险。
该内容是面向实际编码的主动建议,不是警告、否定示例或测试。它先承认 `weak` 引用可能因对象正常释放而合法变为 `nil`,随后却宣称可选绑定比强制解包更差。若代理据此把安全的 nil 分支改成 `!`,对象在读取前释放时会触发运行时崩溃,造成拒绝服务或数据未保存。用户可要求作者保留显式 nil 处理,或仅在有可证明的强生命周期保证时允许强制解包。
- **An object's guaranteed lifetime ends at its last use, not at the closing brace.** Observed lifetimes are an emergent property of the optimizer and _will_ change. Code that depends on when a `deinit` runs is a latent bug.- **`weak`/`unowned` are for breaking reference cycles — nothing else.** Reading a `weak` reference after the strong owner's last use may legitimately give `nil`. Optional binding there is _worse_ than force-unwrap: it turns a loud crash into a silent wrong answer.查看另外 2 个位置
- **An object's guaranteed lifetime ends at its last use, not at the closing brace.** Observed lifetimes are an emergent property of the optimizer and _will_ change. Code that depends on when a `deinit` runs is a latent bug.- **`weak`/`unowned` are for breaking reference cycles — nothing else.** Reading a `weak` reference after the strong owner's last use may legitimately give `nil`. Optional binding there is _worse_ than force-unwrap: it turns a loud crash into a silent wrong answer.- **Better than `weak`: don't build the cycle.** Factor the shared data into a third type both sides reference, turning the cycle into a tree.- **Better than `weak`: don't build the cycle.** Factor the shared data into a third type both sides reference, turning the cycle into a tree.- **Next best: redesign the API** so the object is only reachable through a strong reference. `withExtendedLifetime` works but shifts correctness onto you and spreads through a codebase — treat it as a patch, not a design.- **Keep `deinit` side effects local.** Publishing metrics or firing a global effect from `deinit` sequences against optimizer decisions. Use `defer` at the call site instead, and leave `deinit` for verification.