Question Details

No question body available.

Tags

swift swiftdata swift6

Answers (1)

Accepted Answer Available
Accepted Answer
October 5, 2025 Score: 2 Rep: 293,380 Quality: High Completeness: 100%

Regardless of TestProtocol, it is not possible to isolate SwiftData models to any actor. SwiftData needs to manipulate these models on any isolation domain. PersistentModel is a non-isolated protocol and inherits SendableMetatype. All its requirements (e.g. conformance to Hashable) must be implemented in a non-isolated way.

Even with the "default actor isolation" setting set to the main actor, "regular" @Model classes are not affected by it,

@Model class Foo { var x = 0

init() {} }

nonisolated func f() { // I can totally use Foo's properties in a non-isolated function // this shows that Foo is not affected by the default actor isolation setting print(Foo().x) }

This is because PersistentModel conforms to SendableMetatype. SE-466 specifically carves this out,

Default isolation does not apply in the following cases:

  • ...
  • Declarations whose primary definition directly conforms to a protocol that inherits SendableMetatype
  • ...

Apparently, conformances added by macros count as part of the "primary definition", even though the macro expands to extensions that add those conformances. If you expand the @Model macro, the code fails to compile as expected.

You might be thinking about "why can't the class conform to PersistentModel through an isolated conformance as introduced by SE-0470?" Again, this is because PersistentModel inherits from SendableMetatype. For an example where this wouldn't work, see Rule 2 in that proposal.


Your TestProtocol however, is isolated to the main actor by the "default actor isolation" setting. Note that : PersistentModel here is protocol inheritance, not protocol conformance.

Because of this, by conforming to TestProtocol, the model class implicitly becomes isolated to the main actor. As established above, this will not compile even with an isolated conformance.

You can suppress this implicit main actor isolation using nonisolated, but note that the protocol requirement x also needs to be nonisolated too.

@Model nonisolated class Foo: TestProtocol { nonisolated var x = 0

init() {} }

An IMO better way is to just make the protocol nonisolated,

nonisolated protocol TestProtocol: PersistentModel { var x: Int { get } }