一个服务类,我处理单个实体/对象的所有核心数据事务,我经常发现自己需要访问其他类的信息,我想知道在非ui相关的类中调用这些类是否存在问题。
在下面的代码中,我从DogHouseService
类内部的DogService
类调用dogs
数组,我想知道这是否可能是一个问题。
是否有任何可能的问题调用@Published
属性从ObservableObject
类内部的其他类?
class DogService: ObservableObject{
let manager: CoreDataManager
@Published var dogs: [Dog] = []
init(coreDataManager: CoreDataManager = .instance){
self.manager = coreDataManager
loadDogs()
}
//Adds, Deletes, Updates, etc.
func loadDogs(){
let request = NSFetchRequest<Dog>(entityName: "Dog")
do{
dogs = try manager.context.fetch(request)
}catch let error{
print("Error fetching dogs. (error.localizedDescription)")
}
}
func save(){
self.manager.save()
}
}
其他类class DogHouseService{
let dogService = DogService()
for dog in dogService.dogs{
// do something
}
}
Core Data Manager
class CoreDataManager{
// Singleton
static let instance = CoreDataManager()
@AppStorage(UserDefaults.Keys.iCloudSyncKey) private var iCloudSync = false
/// This property is strictly to be used in the Preview struct in Canvas.
static var preview: CoreDataManager = {
let result = CoreDataManager(inMemory: true)
let viewContext = result.container.viewContext
// create preview objects here
do {
try viewContext.save()
} catch {
}
return result
}()
lazy var context: NSManagedObjectContext = {
return container.viewContext
}()
lazy var container: NSPersistentContainer = {
return setupContainer()
}()
init(inMemory: Bool = false){
/// for preview purposes only, remove if no previews are needed.
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
}
}
func setupContainer()->NSPersistentContainer{
let container = NSPersistentCloudKitContainer(name: "CoreDataContainer")
guard let description = container.persistentStoreDescriptions.first else{
fatalError("###(#function): Failed to retrieve a persistent store description.")
}
description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
// Generate notifications on remote changes
description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
if iCloudSync{
// turn iCloud sync OnThank
let cloudKitContainerIdentifier = "iCloud.com.domain.MyAppName"
let options = NSPersistentCloudKitContainerOptions(containerIdentifier: cloudKitContainerIdentifier)
description.cloudKitContainerOptions = options
}else{
// turn iCloud sync Off
description.cloudKitContainerOptions = nil
}
container.loadPersistentStores { (description, error) in
if let error = error{
print("Error loading Core Data. (error)")
}
}
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
return container
}
func save(){
do{
try context.save()
}catch let error{
print("Error saving Core Data. (error.localizedDescription)")
}
}
}
编辑04/10/2020:添加Core Data Manager代码。
通常你的UI代码使用视图上下文,而你的非UI代码使用背景上下文。您可以在NSManagedObject
子类或NSManagedObject
扩展中编写实体逻辑。这样就可以在不同的上下文中使用相同的逻辑。上下文已经像一个服务了,你不需要为它再添加一个对象。