Use when needing synchronous actor access in tests, legacy delegate callbacks, or performance-critical code. Covers MainActor.assumeIsolated, @preconcurrency protocol conformances, crash behavior, Task vs assumeIsolated.
Use when needing synchronous actor access in tests, legacy delegate callbacks, or performance-critical code. Covers MainActor.assumeIsolated, @preconcurrency protocol conformances, crash behavior, Task vs assumeIsolated.
license
MIT
metadata
{"version":"1.0.0"}
assumeIsolated — Synchronous Actor Access
Synchronously access actor-isolated state when you know you're already on the correct isolation domain.
actorDataStore {
var cache: [String: Data] = [:]
nonisolatedfuncsynchronousRead(key: String) -> Data? {
// Only safe if called from DataStore's executor
assumeIsolated { isolatedinisolated.cache[key]
}
}
}
Common Mistakes
Mistake 1: Silencing Compiler Errors
// ❌ DANGEROUS: Using assumeIsolated to silence warningsfuncunknownContext() {
MainActor.assumeIsolated {
updateUI() // Crashes if not actually on main actor!
}
}
// ✅ When uncertain, use proper asyncfuncunknownContext() async {
awaitMainActor.run {
updateUI()
}
}
Mistake 2: Assuming GCD Main Queue == MainActor
They're usually the same, but not guaranteed. Check documentation or use async.
Mistake 3: Using in Async Context
// ❌ Unnecessary — you already have isolation@MainActorfuncupdateState() async {
MainActor.assumeIsolated { // Pointlessself.state = .ready
}
}
// ✅ Direct access@MainActorfuncupdateState() async {
self.state = .ready
}
When @preconcurrency Becomes Unnecessary
If the protocol later adds MainActor isolation:
// Library update:@MainActorprotocolCaffeineThresholdDelegate: AnyObject {
funccaffeineLevel(atlevel: Double)
}
// Your code — @preconcurrency now warns:// "@preconcurrency attribute on conformance has no effect"extensionRecaffeinater: CaffeineThresholdDelegate {
funccaffeineLevel(atlevel: Double) {
// Direct access, no wrapper needed
}
}
Crash Behavior
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.