切换默认 Actor 隔离为 nonisolated 并补充并发约定
This commit is contained in:
19
AGENTS.md
19
AGENTS.md
@ -36,6 +36,25 @@ iOS 16+ · 仅 iPhone · 仅竖屏。不做 iPad / 横屏 / 低版本 API 适配
|
|||||||
- 对照 Android **行为** 用 UIKit 重写,不翻译 Compose 语法
|
- 对照 Android **行为** 用 UIKit 重写,不翻译 Compose 语法
|
||||||
- ViewModel 属性供读取,UI 更新由 View 在回调中主动触发
|
- 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 必须写 `///` 文档注释,说明职责与用途;复杂内部逻辑按需补充。不写废话注释、不写过时注释。
|
`class` / `struct` / `enum`、协议及公开 API 必须写 `///` 文档注释,说明职责与用途;复杂内部逻辑按需补充。不写废话注释、不写过时注释。
|
||||||
|
|||||||
@ -264,7 +264,7 @@
|
|||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SWIFT_APPROACHABLE_CONCURRENCY = YES;
|
SWIFT_APPROACHABLE_CONCURRENCY = YES;
|
||||||
SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor;
|
SWIFT_DEFAULT_ACTOR_ISOLATION = nonisolated;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
|
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
@ -300,7 +300,7 @@
|
|||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SWIFT_APPROACHABLE_CONCURRENCY = YES;
|
SWIFT_APPROACHABLE_CONCURRENCY = YES;
|
||||||
SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor;
|
SWIFT_DEFAULT_ACTOR_ISOLATION = nonisolated;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
|
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
@ -443,7 +443,7 @@
|
|||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
SWIFT_APPROACHABLE_CONCURRENCY = YES;
|
SWIFT_APPROACHABLE_CONCURRENCY = YES;
|
||||||
SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor;
|
SWIFT_DEFAULT_ACTOR_ISOLATION = nonisolated;
|
||||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||||
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
|
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
@ -466,7 +466,7 @@
|
|||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
SWIFT_APPROACHABLE_CONCURRENCY = YES;
|
SWIFT_APPROACHABLE_CONCURRENCY = YES;
|
||||||
SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor;
|
SWIFT_DEFAULT_ACTOR_ISOLATION = nonisolated;
|
||||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||||
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
|
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
|
|||||||
Reference in New Issue
Block a user