AI 辅助 iOS 开发防坑指南:在 Objective-C 老项目中打造“不漏网”的研发工作流
AI 辅助 iOS 开发防坑指南:在 Objective-C 老项目中打造“不漏网”的研发工作流
背景
在大模型(LLM)普及的今天,越来越多的开发者习惯于让 AI 分析需求、生成文档、编写代码甚至进行 Code Review。然而,在一些历史包袱较重、动态特性活跃的 Objective-C(OC)iOS 老项目中,许多人发现:即便每一步都让 AI 确认了,上线后依然会遗漏各种奇奇怪怪的小问题。
最典型的场景莫过于:
- 新增了某个局部多语言挂件,结果因为 Category 的实现方式,导致首页语言切换时整个页面卡住或文案不刷新。
- 为了解决并发问题修改了网络请求的
stop/cancel逻辑,结果导致某些地方的回调(Completion Block)被静默拦截,UI 的 Loading 菊花转个不停,甚至引发了其他业务模块的逻辑雪崩。
为什么大模型明明通过了“最小、最优改动”和“影响范围”的自检,线上依然会翻车?在 OC 老项目中,我们应该如何重新设计与 AI 的协作工作流?本文将为你深度复盘技术根因,并提供一套可落地的 “六步质量门” AI 研发工作流。
一、 为什么 AI 总是低估 OC 老项目的改动风险?
AI 的代码分析能力基于上下文,但 Objective-C 具有极强的运行时(Runtime)动态特性。许多老项目里充斥着“隐性依赖”与“非显式调用”,这些是 AI 很难一眼看穿的。
1. 致命的 Category 滥用与方法覆盖
Category 是 OC 的一大神器,也是老项目维护者的噩梦。
- 同名覆盖风险:如果 AI 在 Category 里新增了一个方法,而该方法在原类或其他 Category 里已经存在,运行时会导致其中一个方法被无预警覆盖。
- 全局副作用:有些老项目为了偷懒,在
UILabel、NSString或NSBundle的 Category 里 Hook 或重写了系统方法(如localizedStringForKey:...)。AI 在只看局部上下文时,根本不知道这个全局 Category 会在语言切换或资源读取时被意外触发,进而导致首页等多语言刷新链路断裂。
2. 被忽视的请求生命周期与回调契约
网络请求的取消(stop/cancel)看似简单,实则牵一发动全身。
- 回调静默丢失:在许多业务逻辑中,UI 的状态恢复(如关闭菊花、恢复按钮点击)强依赖于请求的
completion执行。如果底层执行了stop却直接return且没有调用 completion block,调用方就会永远处于“等待中”状态。 - 共享状态污染:老项目底层往往存在单例或者共享的网络管理器。AI 修改了针对“第二个请求”的
stop拦截,可能不小心把持有同一个 owner 或 task 标记的第一个正常请求也给误伤了。
二、 拒绝“事后一问”:重新设计 AI 的协作节奏
大部分人的 AI 协作流程是:接收需求 ➔ AI 分析生成文档 ➔ 人工确认 ➔ AI 编写/修改代码 ➔ 人工验证新功能 ➔ 让 AI 确认是否是最小、最优改动及影响范围 ➔ 提交代码。
这个流程最大的硬伤在于:影响面评估(Impact Analysis)发生得太晚了!
当代码已经修改完毕,AI 会倾向于基于当前的 diff 去做合理解释(即“证真”),而不是站在全项目调用关系和历史踩坑的角度去反证。为了解决这个问题,我们需要把 AI 从单纯的“代码实现者”升级为“架构审计员”,将质量控制前移。
三、 落地:构建“六步质量门” AI 工作流
我们要将单次的需求闭环,升级为系统级的变更闭锁机制。核心框架如下:
1 | 1. 风险分类识别 ➔ 2. 引导代码地图 ➔ 3. 约束禁止方案 ➔ 4. 固化回归测试 ➔ 5. 证据型 Diff 审查 ➔ 6. 事故沉淀复盘 |
第 1 步:变更分类(Classify Before Coding)
在开始写第一行代码前,先不要让 AI 给方案,而是把需求丢给它,让它判断是否命中高风险变更分类。
📌 提示词模版:
1 | 你是一个资深 iOS Objective-C 研发专家。 |
第 2 步:构建代码地图(Map Out Dependencies)
AI 需要充足的上下文。通过第 1 步得到的关键词和关联文件,命令 AI 梳理出系统的隐性依赖链条。
📌 针对多语言需求的提示词:
1 | 在进行代码修改前,请帮我梳理项目中的多语言切换链路: |
📌 针对网络请求 stop 需求的提示词:
1 | 在修改请求 stop 逻辑前,请帮我梳理网络层回调契约: |
第 3 步:方案设计增加“禁止清单”(Define No-Go Zones)
不仅要问 AI“怎么做最好”,更要规定“绝对不能怎么做”。在 OC 开发中,应该定死以下硬性约束:
- Category 铁律:业务需求严禁直接通过 Category 去重写或覆盖已有方法;Category 中新增的方法必须强制加业务前缀(如
xxx_method),杜绝同名冲突。 - 请求契约铁律:只要调用方传入了 completion block,无论请求是成功、失败、超时还是被取消,底层都必须且只能执行一次回调,严禁默默 return。
- 多语言铁律:UI 控件不要在初始化时直接将翻译后的字符串固化,必须保存 Key 或建立动态刷新监听。
第 4 步:把“痛点”固化为自动化测试
不要寄希望于人工每次都记得去测边缘 case。将曾经出过问题的逻辑写成防回滚(Anti-Regression)测试。
示例 1:防止多语言切换失效的单元测试
1 | - (void)testHomeWidgetTitleUpdatesAfterLanguageChanged { |
示例 2:确保网络请求取消后必定回调的测试
1 | - (void)testCancelRequestStillCallsCompletionOnce { |
第 5 步:提交前实施“证据型” Diff 审查
代码写完后,不要含糊地问 AI “这个改动安全吗”。你要逼它拿出“调用链路证据”来。
📌 提交前审查提示词:
1 | 请对本次代码改动的 Diff 进行安全审查。 |
第 6 步:事故复盘沉淀到 AI_REVIEW.md
只要线上漏掉了一个问题,就把这个 Bug 的场景、成因、检索关键词、测试方法写进项目根目录的 AI_REVIEW.md 中。
下一次开发新需求时,直接把这个 Markdown 文件的内容作为系统上下文喂给 AI:
“这是我们项目历史上的 Bug 避坑清单,本次需求分析时,请严格对照其中的 Checklist,确保不重蹈覆辙。”
四、 总结:从“相信 AI” 到 “契约式协作”
AI 是极佳的生产力放大器,但它没有“历史记忆”,对 OC 这种高动态运行时语言的隐式风险也缺乏直觉。
解决线上遗漏的关键,不是禁用 AI,而是改变对齐方式:
- 别让 AI 在改完代码后再评估影响面:在分析设计阶段就逼它做风险分类,梳理代码地图。
- 规范契约,拒绝野路子:确立“Category 加前缀”、“取消请求也必须回调”等硬性架构约束。
- 沉淀自动化防线:把每一次线上血泪教训,变成一行行 XCTest 代码与
AI_REVIEW.md清单。
把大模型放到合理的防线位置上,它才会从一个“写 Bug 的实习生”,真正成长为帮你“守护老项目稳定”的资深技术专家。