关于 ios-chaos-monkey
ios-chaos-monkey 是面向 iOS 和 Swift 开发者的崩溃排查指南。规则按风险优先级覆盖并发、内存、持久化等运行时问题,并要求先用测试复现崩溃再修复。
主要功能
- 01按优先级排列的崩溃风险规则
- 02并发与数据竞争检查
- 03内存和死锁指南
- 04异步任务与取消检查
- 05持久化和文件 I/O 风险
- 06先测试复现崩溃的流程
适用场景
- 01审查 Swift 并发代码中的数据竞争
- 02检查异步代码的取消与延续泄漏
- 03测试持久化和文件 I/O 故障风险
- 04在修复前编写失败的崩溃测试
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ pproenca/ dot-skills --skill ios-chaos-monkey安装后在 Claude Code 中输入/ios-chaos-monkey确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
metadata.jsonassets/templates/_template.mdreferences/_sections.mdasync-actor-hop-starvation.mdasync-continuation-leak.mdasync-detached-task-leak.mdasync-missing-cancellation.mdasync-task-group-error.mdasync-unsafe-sendable.mddead-actor-reentrancy.mddead-mainactor-blocking.mddead-queue-hierarchy.mddead-recursive-lock.mddead-semaphore-in-async.mddead-sync-on-main.mdexhaust-file-descriptor-leak.mdexhaust-memory-warning-ignored.mdexhaust-thread-explosion.mdexhaust-unbounded-task-spawn.mdexhaust-urlsession-leak.mdio-concurrent-file-write.mdio-coredata-cross-thread.mdio-filemanager-race.mdio-keychain-thread-safety.mdio-plist-concurrent-mutation.mdio-swiftdata-background.mdmem-async-task-self-capture.mdmem-closure-retain-cycle.mdmem-combine-sink-retain.mdmem-delegate-strong-reference.md详细介绍
iOS 混沌猴 — 崩溃猎手最佳实践
面向 iOS 和 Swift 应用的对抗式崩溃排查指南。包含 8 个类别中的 47 条规则,并按崩溃严重程度排序。每条规则都遵循 TDD:先展示危险代码,再编写能证明存在 bug 的失败测试,最后修复问题并使测试通过。
Clinic 架构约定(iOS 26 / Swift 6.2)
本技能中的所有指导均基于 Clinic 模块化 MVVM-C 架构:
- Feature 模块仅导入
Domain+DesignSystem(绝不导入Data或其他同级 Feature) - App target 是汇聚点,负责管理
DependencyContainer、具体协调器以及 Route Shell 接线 Domain保持纯 Swift,并定义模型以及 repository、*Coordinating、ErrorRouting和AppError契约Data负责 SwiftData/网络/同步/重试/后台 I/O,并实现 Domain 协议- 读写流程默认采用过期数据优先、后台重新验证的读取方式,以及乐观排队写入
- ViewModel 直接调用 repository 协议(默认不设 use-case/interactor 层)
适用场景
在以下情况下,请参考这些指南:
- 排查 Swift 中的数据竞争、死锁和并发崩溃
- 审计内存管理,查找循环引用和释放后使用问题
- 检查 async/await 代码中的取消处理和 continuation 泄漏
- 对文件 I/O 和 CoreData/SwiftData 持久化层进行压力测试
- 在实现修复前编写崩溃复现测试
按优先级划分的规则类别
| 优先级 | 类别 | 影响 | 前缀 |
|---|---|---|---|
| 1 | 数据竞争与线程安全 | 严重 | race- |
| 2 | 内存损坏与泄漏 | 严重 | mem- |
| 3 | 死锁与线程饥饿 | 高 | dead- |
| 4 | Async/Await 与结构化并发 | 高 | async- |
| 5 | 文件 I/O 与持久化损坏 | 中高 | io- |
| 6 | 集合与状态变更 | 中 | mut- |
| 7 | 资源耗尽 | 中 | exhaust- |
| 8 | Objective-C 互操作陷阱 | 低至中 | objc- |
快速参考
1. 数据竞争与线程安全(严重)
race-dictionary-concurrent-write- 并发修改 Dictionary 会因 EXC_BAD_ACCESS 崩溃race-array-concurrent-append- 并发向 Array 追加元素会损坏内部缓冲区race-property-access- 多线程间未同步地读写属性race-lazy-initialization- 并发时惰性属性被重复初始化race-singleton-initialization- 非原子单例会暴露尚未完全构造的状态race-bool-flag- 非原子 Bool 标志会造成先检查后执行的竞争race-closure-capture-mutation- 闭包跨线程捕获可变引用race-delegate-nilification- 活跃回调期间将 Delegate 设为 nil
2. 内存损坏与泄漏(严重)
mem-closure-retain-cycle- 转义闭包中对自身的强引用会形成保留循环mem-timer-retain-cycle- Timer 保留目标,形成难以发现的保留循环mem-delegate-strong-reference- 强委托引用会阻止对象释放mem-unowned-crash- 所有者释放后,非拥有引用会导致崩溃mem-notification-observer-leak- 移除观察者后,NotificationCenter 仍会保留闭包mem-combine-sink-retain- 未存储 cancellable 时,Combine sink 会保留 selfmem-async-task-self-capture- Task 捕获 self,使其生命周期超出预期范围
3. 死锁与线程饥饿(高)
dead-sync-on-main- 在主线程调用 DispatchQueue.main.sync 会立即导致死锁dead-recursive-lock- 在同一串行队列上递归获取锁dead-actor-reentrancy- Actor 可重入会产生意外的交错执行dead-semaphore-in-async- 在异步上下文中调用 Semaphore.wait() 会导致线程池死锁dead-queue-hierarchy- Dispatch 队列目标层级反转会导致死锁dead-mainactor-blocking- 使用同步的繁重工作阻塞 MainActor
4. Async/Await 与结构化并发(高)
async-missing-cancellation- 缺少 Task.isCancelled 检查,导航后仍会浪费资源async-detached-task-leak- Detached task 未提供取消句柄,会导致工作泄漏async-task-group-error- TaskGroup 会静默丢弃子任务错误async-continuation-leak- CheckedContinuation 从未恢复,会导致等待中的任务泄漏async-actor-hop-starvation- 热循环中过多跳转到 MainActor 会使 UI 更新饥饿async-unsafe-sendable- @unchecked Sendable 会向编译器隐藏数据竞争
5. 文件 I/O 与持久化损坏(中高)
io-concurrent-file-write- 并发写入文件时若未协调,会导致数据损坏io-coredata-cross-thread- 在错误的线程上访问 CoreData NSManagedObjectio-swiftdata-background- 在错误的 ModelContext 中访问 SwiftData 模型io-plist-concurrent-mutation- UserDefaults 并发读写会产生过期值io-filemanager-race- FileManager 先检查文件是否存在再使用,会造成 TOCTOU 竞争io-keychain-thread-safety- 从多个线程访问 Keychain 会返回意外错误
6. 集合与状态变更(中)
mut-enumerate-and-mutate- 遍历期间修改集合会导致运行时崩溃mut-kvo-dealloc-crash- 释放对象前未移除 KVO 观察者会导致崩溃mut-index-out-of-bounds- 未进行边界检查就访问数组索引会导致崩溃mut-force-unwrap- 在生产环境中强制解包可选值,遇到 nil 时会导致崩溃mut-enum-future-cases- 不穷尽的 switch 遇到未知枚举情况时会导致崩溃
7. 资源耗尽(中)
exhaust-unbounded-task-spawn- 在循环中无限制地生成任务会耗尽内存exhaust-thread-explosion- GCD 在并发负载下会创建无限数量的线程exhaust-urlsession-leak- 未使 URLSession 失效会导致代理和连接泄漏exhaust-file-descriptor-leak- 未关闭文件句柄会导致文件描述符泄漏exhaust-memory-warning-ignored- 忽略低内存警告会触发 Jetsam 终止进程
8. Objective-C 互操作陷阱(低至中)
objc-unrecognized-selector- 缺少 @objc 注解会因无法识别的选择器而导致崩溃objc-nsnull-in-json- 访问已解码 JSON 集合中的 NSNull 会导致崩溃objc-bridge-type-mismatch- Swift/ObjC 桥接类型不匹配会导致运行时崩溃objc-dynamic-dispatch- 缺少 dynamic 关键字会导致方法替换失效
使用方法
阅读各个参考文件,了解详细说明和代码示例:
参考文件
| 文件 | 说明 |
|---|---|
| references/_sections.md | 类别定义和排序 |
| assets/templates/_template.md | 新规则模板 |
| metadata.json | 版本和参考信息 |
评论
支持 Markdown