CoreData and Swift's Actor and Sendable

1.1k Views Asked by At

I am trying to understand Swift's Actors, but failed. I am playing around with the following example.
I want to setup a LocalStore that uses an NSPersistentContainer.
The struct LocalStore should be used by a StoreManager declared as

actor StoreManager {
  private let localStore = LocalStore()
  init() {
    localStore.test()
  }
}  

LocalStore is declared as

import CoreData
import Foundation

struct LocalStore: Sendable {
  private let localPersistentContainer = NSPersistentContainer()

  func test() {
    print("test")
  }
}

Here I get 2 compiler errors, shown here as comments:

  • import CoreData // Add '@_predatesConcurrency' to suppress 'Sendable'-related warnings from module 'CoreData'
  • private let localPersistentContainer = NSPersistentContainer() // Stored property 'localPersistentContainer' of 'Sendable'-conforming struct 'LocalStore' has non-sendable type 'NSPersistentContainer'

I neither know if it is save or advisable to suppress 'Sendable'-related warnings from module 'CoreData', nor what to do with the non-sendable type 'NSPersistentContainer'.
Any help is welcome.

1

There are 1 best solutions below

0
On BEST ANSWER

By now I understand the situation a little better.
LocalStore is declared as Sendable, i.e. it should be possible to be passed around thread-safe. Now assume its property localPersistentContainer had been declared as follows:

let localPersistentContainer = NSPersistentContainer()  

NSPersistentContainer has some properties that can be set, like persistentStoreDescriptions. It is thus possible that such a property can be changed within LocalStore, as well as by anything that has been passed LocalStore to, i.e. this would not be thread-safe. In this case the warning

Stored property 'localPersistentContainer' of 'Sendable'-conforming struct 'LocalStore' has non-sendable type 'NSPersistentContainer'  

is justified.
However, in my case localPersistentContainer has been declared as follows:

private let localPersistentContainer = NSPersistentContainer()  

This means that anything that receives a LocalStore cannot access the private property localPersistentContainer, and thus the compiler warning is not justified, since the compiler is of course aware of that.

As the other compiler warning suggested,

@_predatesConcurrency import CoreData  

suppresses all Sendable warnings created by the CoreData module. While this works, it is to my mind dangerous because it suppresses also justified warnings.