Switch default actor isolation to nonisolated and document concurrency conventions.
Align app and test targets on nonisolated defaults so ViewModels stay off MainActor by default, and capture the resulting patterns in AGENTS.md. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
19
AGENTS.md
19
AGENTS.md
@ -36,6 +36,25 @@ iOS 16+ · 仅 iPhone · 仅竖屏。不做 iPad / 横屏 / 低版本 API 适配
|
||||
- 对照 Android **行为** 用 UIKit 重写,不翻译 Compose 语法
|
||||
- ViewModel 属性供读取,UI 更新由 View 在回调中主动触发
|
||||
|
||||
## Swift 并发与 Actor
|
||||
|
||||
工程 **Default Actor Isolation** 配置为 **`nonisolated`**(`suixinkan` 与 `suixinkanTests` 均为 `SWIFT_DEFAULT_ACTOR_ISOLATION = nonisolated`)。新类型默认不隐式绑定 `@MainActor`,与命令式 UIKit + 显式刷新风格一致。
|
||||
|
||||
| Target | Default Actor Isolation |
|
||||
|--------|-------------------------|
|
||||
| `suixinkan` | `nonisolated` |
|
||||
| `suixinkanTests` | `nonisolated` |
|
||||
|
||||
编写约定:
|
||||
|
||||
- **ViewModel / Model**:保持 `nonisolated`,不依赖默认 MainActor;纯逻辑与校验可用 `nonisolated static`。
|
||||
- **需要主线程的类型**:在类型上**显式**标注 `@MainActor`(如 `APIClient`、`AuthAPI`、`ProfileAPI`、`NetworkServices`、`OSSUploadService`、`AppRouter`)。
|
||||
- **UI 更新**:在 `UIViewController` 内通过 `Task { @MainActor in ... }` 或已在主线程的回调中刷新 UI,不假设 ViewModel 调用方一定在主 Actor;`onStateChange` 回调应切回主线程再改 UI。
|
||||
- **网络与可发送类型**:请求/环境等跨边界类型保持 `nonisolated` + `Sendable`(如 `APIRequest`),避免无意引入 actor 隔离冲突。
|
||||
- **单元测试**:target 默认为 `nonisolated`;`MockURLSession` 等替身保持 `nonisolated`。需要构造 `@MainActor` 类型(`APIClient`、`AuthAPI` 等)的测试类应显式标 `@MainActor`。
|
||||
|
||||
新增代码不要为「凑隔离」给 ViewModel 或普通 model 加 `@MainActor`;仅 UI 入口、共享网络单例等确需主线程协调处显式标注。
|
||||
|
||||
## 代码注释
|
||||
|
||||
`class` / `struct` / `enum`、协议及公开 API 必须写 `///` 文档注释,说明职责与用途;复杂内部逻辑按需补充。不写废话注释、不写过时注释。
|
||||
|
||||
Reference in New Issue
Block a user