关于 axiom-assume-isolated
介绍 Swift 中的 `assumeIsolated`,用于确认当前隔离域正确时同步访问 Actor 隔离状态。内容说明适用场景、错误隔离时的崩溃行为,以及 `await` 等替代方式。
主要功能
- 01同步访问 Actor 隔离状态
- 02在测试中使用 MainActor.assumeIsolated
- 03将 assumeIsolated 用于委托回调
- 04了解隔离检查与崩溃行为
- 05隔离不确定时选择异步替代方式
适用场景
- 01同步测试 MainActor 代码
- 02处理文档保证在主线程执行的委托回调
- 03避免同步代码中的异步切换
- 04检查不安全的隔离假设
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ charleswiltgen/ axiom --skill axiom-assume-isolated安装后在 Claude Code 中输入/axiom-assume-isolated确认已加载。
详细介绍
assumeIsolated —— 同步访问 Actor 隔离状态
当你确定当前已处于正确的隔离域时,同步访问 Actor 隔离状态。
使用时机
✅ 适用于:
- 同步测试 MainActor 代码(避免 Task 开销)
- 文档注明在主线程运行的旧式委托回调
- 需要避免 async 跳转开销的性能关键代码
- 回调保证在特定 Actor 上运行的协议一致性实现
❌ 不适用于:
- 不确定当前的隔离状态时(改用
await) - 已处于 async 上下文中(你已具备隔离状态)
- 需要跨 Actor 调用时(改用 async)
- 回调来源未知或不可信时
API 参考
MainActor.assumeIsolated
static func assumeIsolated<T>(
_ operation: @MainActor () throws -> T,
file: StaticString = #fileID,
line: UInt = #line
) rethrows -> T where T: Sendable
行为:同步执行。如果不在 MainActor 的串行执行器上,则崩溃。
自定义 Actor 的 assumeIsolated
func assumeIsolated<T>(
_ operation: (isolated Self) throws -> T,
file: StaticString = #fileID,
line: UInt = #line
) rethrows -> T where T: Sendable
Task 与 assumeIsolated
| 方面 | Task { @MainActor in } | MainActor.assumeIsolated |
|---|---|---|
| 时机 | 延迟执行(下一个运行循环) | 同步执行(内联) |
| Async 支持 | 支持(可使用 await) | 不支持(仅限同步) |
| 上下文 | 可在任意上下文中使用 | 必须是同步函数 |
| 失败方式 | 仍会运行 | 如果隔离状态不正确则崩溃 |
| 使用场景 | 启动异步工作 | 验证并访问隔离状态 |
模式
模式 1:测试 MainActor 代码
@Test func viewModelUpdates() {
MainActor.assumeIsolated {
let vm = ViewModel()
vm.update()
#expect(vm.state == .updated)
}
}
模式 2:旧式委托回调
摘自 WWDC 2024-10169 —— 文档保证回调在主线程上执行时:
@MainActor
class LocationDelegate: NSObject, CLLocationManagerDelegate {
var location: CLLocation?
// CLLocationManager created on main thread delivers callbacks on main thread
nonisolated func locationManager(
_ manager: CLLocationManager,
didUpdateLocations locations: [CLLocation]
) {
MainActor.assumeIsolated {
self.location = locations.last
}
}
}
模式 3:@preconcurrency 简写
@preconcurrency 是等效的简写形式,会自动包装在 assumeIsolated 中:
// ❌ Manual approach (verbose)
extension MyClass: SomeDelegate {
nonisolated func callback() {
MainActor.assumeIsolated {
self.updateUI()
}
}
}
// ✅ Using @preconcurrency (equivalent, cleaner)
extension MyClass: @preconcurrency SomeDelegate {
func callback() {
self.updateUI() // Compiler wraps in assumeIsolated
}
}
协议添加隔离状态后:@preconcurrency 将不再需要,编译器也会发出警告。
模式 4:在 assumeIsolated 前检查线程
当调用方上下文未知时(例如,在库代码中):
func getView() -> UIView {
if Thread.isMainThread {
return createHostingViewOnMain()
} else {
return DispatchQueue.main.sync {
createHostingViewOnMain()
}
}
}
private func createHostingViewOnMain() -> UIView {
MainActor.assumeIsolated {
let hosting = UIHostingController(rootView: MyView())
return hosting.view
}
}
模式 5:访问自定义 Actor
actor DataStore {
var cache: [String: Data] = [:]
nonisolated func synchronousRead(key: String) -> Data? {
// Only safe if called from DataStore's executor
assumeIsolated { isolated in
isolated.cache[key]
}
}
}
常见错误
错误 1:压制编译器错误
// ❌ DANGEROUS: Using assumeIsolated to silence warnings
func unknownContext() {
MainActor.assumeIsolated {
updateUI() // Crashes if not actually on main actor!
}
}
// ✅ When uncertain, use proper async
func unknownContext() async {
await MainActor.run {
updateUI()
}
}
错误 2:认为 GCD 主队列等同于 MainActor
它们通常相同,但并非总是如此。请查阅文档或改用 async。
错误 3:在 Async 上下文中使用
// ❌ Unnecessary — you already have isolation
@MainActor
func updateState() async {
MainActor.assumeIsolated { // Pointless
self.state = .ready
}
}
// ✅ Direct access
@MainActor
func updateState() async {
self.state = .ready
}
@preconcurrency 不再需要的情况
如果协议之后添加了 MainActor 隔离:
// Library update:
@MainActor
protocol CaffeineThresholdDelegate: AnyObject {
func caffeineLevel(at level: Double)
}
// Your code — @preconcurrency now warns:
// "@preconcurrency attribute on conformance has no effect"
extension Recaffeinater: CaffeineThresholdDelegate {
func caffeineLevel(at level: Double) {
// Direct access, no wrapper needed
}
}
崩溃行为
根据 Apple 文档:
“如果当前上下文没有运行在该 Actor 的串行执行器上……此方法将以致命错误崩溃。”
触发崩溃是有意为之:与其让竞态条件损坏用户数据,不如直接崩溃。
资源
WWDC:2024-10169
文档:/swift/mainactor/assumeisolated、/swift/actor/assumeisolated
技能:axiom-swift-concurrency
评论
支持 Markdown