axiom-assume-isolated by charleswiltgen/axiom
npx skills add https://github.com/charleswiltgen/axiom --skill axiom-assume-isolated当你确定自己已处于正确的隔离域时,可同步访问 actor 隔离状态。
✅ 适用于以下情况:
❌ 不适用于以下情况:
await)static func assumeIsolated<T>(
_ operation: @MainActor () throws -> T,
file: StaticString = #fileID,
line: UInt = #line
) rethrows -> T where T: Sendable
行为:同步执行。如果不在 MainActor 的串行执行器上,则崩溃。
func assumeIsolated<T>(
_ operation: (isolated Self) throws -> T,
file: StaticString = #fileID,
line: UInt = #line
) rethrows -> T where T: Sendable
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 方面 | Task { @MainActor in } | MainActor.assumeIsolated |
|---|---|---|
| 时机 | 延迟执行(下一个运行循环) | 同步执行(内联) |
| 异步支持 | 支持(可 await) | 不支持(仅同步) |
| 上下文 | 可从任何上下文调用 | 必须在同步函数中调用 |
| 失败模式 | 无论如何都会运行 | 如果隔离错误则崩溃 |
| 使用场景 | 启动异步工作 | 验证并访问隔离状态 |
@Test func viewModelUpdates() {
MainActor.assumeIsolated {
let vm = ViewModel()
vm.update()
#expect(vm.state == .updated)
}
}
来自 WWDC 2024-10169 — 当文档保证在主线程交付时:
@MainActor
class LocationDelegate: NSObject, CLLocationManagerDelegate {
var location: CLLocation?
// 在主线程创建的 CLLocationManager 在主线程交付回调
nonisolated func locationManager(
_ manager: CLLocationManager,
didUpdateLocations locations: [CLLocation]
) {
MainActor.assumeIsolated {
self.location = locations.last
}
}
}
@preconcurrency 是等效的简写形式 — 会自动包装在 assumeIsolated 中:
// ❌ 手动方式(冗长)
extension MyClass: SomeDelegate {
nonisolated func callback() {
MainActor.assumeIsolated {
self.updateUI()
}
}
}
// ✅ 使用 @preconcurrency(等效,更简洁)
extension MyClass: @preconcurrency SomeDelegate {
func callback() {
self.updateUI() // 编译器会包装在 assumeIsolated 中
}
}
当协议添加隔离时:@preconcurrency 变得不必要,编译器会发出警告。
当调用者上下文未知时(例如库代码):
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
}
}
actor DataStore {
var cache: [String: Data] = [:]
nonisolated func synchronousRead(key: String) -> Data? {
// 仅当从 DataStore 的执行器调用时安全
assumeIsolated { isolated in
isolated.cache[key]
}
}
}
// ❌ 危险:使用 assumeIsolated 来静默警告
func unknownContext() {
MainActor.assumeIsolated {
updateUI() // 如果实际不在主 actor 上,会崩溃!
}
}
// ✅ 不确定时,使用正确的异步方式
func unknownContext() async {
await MainActor.run {
updateUI()
}
}
它们通常相同,但并非绝对保证。请查阅文档或使用异步方式。
// ❌ 不必要 — 你已拥有隔离
@MainActor
func updateState() async {
MainActor.assumeIsolated { // 无意义
self.state = .ready
}
}
// ✅ 直接访问
@MainActor
func updateState() async {
self.state = .ready
}
如果协议后来添加了 MainActor 隔离:
// 库更新:
@MainActor
protocol CaffeineThresholdDelegate: AnyObject {
func caffeineLevel(at level: Double)
}
// 你的代码 — @preconcurrency 现在会警告:
// "@preconcurrency attribute on conformance has no effect"
extension Recaffeinater: CaffeineThresholdDelegate {
func caffeineLevel(at level: Double) {
// 直接访问,无需包装
}
}
根据 Apple 文档:
"如果当前上下文未在 actor 的串行执行器上运行...此方法将以致命错误崩溃。"
故意触发陷阱:崩溃总比因竞态条件损坏用户数据要好。
WWDC:2024-10169
文档:/swift/mainactor/assumeisolated, /swift/actor/assumeisolated
技能:axiom-swift-concurrency
每周安装量
91
代码库
GitHub 星标数
601
首次出现
2026年1月21日
安全审计
安装于
opencode76
claude-code72
codex71
gemini-cli69
cursor69
github-copilot66
Synchronously access actor-isolated state when you know you're already on the correct isolation domain.
✅ Use when:
❌ Don't use when:
await instead)static func assumeIsolated<T>(
_ operation: @MainActor () throws -> T,
file: StaticString = #fileID,
line: UInt = #line
) rethrows -> T where T: Sendable
Behavior : Executes synchronously. Crashes if not on MainActor's serial executor.
func assumeIsolated<T>(
_ operation: (isolated Self) throws -> T,
file: StaticString = #fileID,
line: UInt = #line
) rethrows -> T where T: Sendable
| Aspect | Task { @MainActor in } | MainActor.assumeIsolated |
|---|---|---|
| Timing | Deferred (next run loop) | Synchronous (inline) |
| Async support | Yes (can await) | No (sync only) |
| Context | From any context | Must be sync function |
| Failure mode | Runs anyway | Crashes if wrong isolation |
| Use case | Start async work | Verify + access isolated state |
@Test func viewModelUpdates() {
MainActor.assumeIsolated {
let vm = ViewModel()
vm.update()
#expect(vm.state == .updated)
}
}
From WWDC 2024-10169 — When documentation guarantees main thread delivery:
@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
}
}
}
@preconcurrency is equivalent shorthand — wraps in assumeIsolated automatically:
// ❌ 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
}
}
When protocol adds isolation : @preconcurrency becomes unnecessary and compiler warns.
When caller context is unknown (e.g., library code):
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
}
}
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]
}
}
}
// ❌ 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()
}
}
They're usually the same, but not guaranteed. Check documentation or use 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
}
If the protocol later adds MainActor isolation:
// 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
}
}
Per Apple documentation:
"If the current context is not running on the actor's serial executor... this method will crash with a fatal error."
Trapping is intentional : Better to crash than corrupt user data with a race condition.
WWDC : 2024-10169
Docs : /swift/mainactor/assumeisolated, /swift/actor/assumeisolated
Skills : axiom-swift-concurrency
Weekly Installs
91
Repository
GitHub Stars
601
First Seen
Jan 21, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode76
claude-code72
codex71
gemini-cli69
cursor69
github-copilot66
Swift Actor 线程安全持久化:构建离线优先应用的编译器强制安全数据层
1,700 周安装
Solidity智能合约审计员 | 专业安全漏洞检测与Gas优化审计工具
111 周安装
高级 DevOps 工程师工具包 | 生产级 CI/CD、Kubernetes、Terraform、云架构与可观测性
111 周安装
Star Office UI:开源像素办公室看板,AI助手状态可视化与团队协作仪表盘
110 周安装
规范驱动开发 (Spec-Driven Development) - n8n 开发流程与代码规范一致性指南
71 周安装
DBOS TypeScript 最佳实践:构建可靠、容错的持久化工作流应用指南
112 周安装
功能优先创意改编指南:从DNA提取到正交合成,避免表面翻译陷阱
116 周安装