在多个 VC 中处理 NSManagedObjects 和 CoreData 的最佳实践

best practice handling NSManagedObjects and CoreData in multiple VC's

我可以在这方面采纳你的建议

我重组了我的整个应用程序,使用 coreData 这样我就可以保存我的应用程序的 Main Class:“FooBar” 我还将完整的业务逻辑转移到那个 NSManagedObject subclass FooBar() 这就是为什么我需要使用某种方便的 init 来启动我自己的计算值的方法等等 这是我的 class 定义:

Import Foundation
import CoreData
import UIKit

@objc(FooBar)
public class FooBar: NSManagedObject {
    
    var context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext // used for other CD interactions inside this class
    var member1 = Int()
    var member2 = Double()
    var member3:Double = 0
    var fooPack:[FooPacks] = []
    ...
    
    
    convenience init(   param1: Int16
                     ,  param2: String?
                     ,  param3: Float
                     ,  param4: String?
                     ,  param5: Float
                     ,  fooPack: NSSet
                     ,  entity: NSEntityDescription
                     ,  context: NSManagedObjectContext?
                    ) {
        self.init(entity: entity, insertInto: context)
    
        self.param1 = param1
        self.param2 = param2
        self.param3 = param3
        self.param4 = param4
        self.param5 = param5
        self.addToUsedfooBarPacks(fooBarPack)
        
        self.build()
    }
    
    func build() {
        // i do something
    }
    
    func method1() {
        // i do something
    }

当我在 viewController 中初始化我的 FooBar class 时,我通过以下方式执行此操作:

self.fooBar = FooBar.init(param1: var1,
                              param2: var2,
                              iparam3: var3,
                              param4: var4,
                              param5: var5,
                              fooPack: var6,
                              entity: FooEntity,
                              context: context)

每当我修改这个 class 的任何实例时,我都会这样做:

self.fooBar.member2 = newValue
self.fooBar.build()

然后在特定点(在多个 VC 中)我然后调用将该实例保存到 CoreData:

let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
do {
        try context.save()
    }catch{
        print("\(error)")
    }

通过这种方法,我经常不得不处理错误和意外行为,例如: do块执行成功,但是对象还没有保存!?

我经常将 FooBar 实例交给另一个 ViewController 并尝试将它们保存在那里, 但这似乎不是更新以前获取的对象的正确方法

在我看来,这与我处理上下文变量的方式有关。 这正是我向您寻求建议的原因..

处理这种情况的最佳方法是什么,我想在多个不同的 ViewController 中修改和保存实例? 在过去的几个月里,我已经学到了很多关于 CoreData 的新知识,但我似乎错过了一些重要的东西..

请大家帮帮我 :)

您正在使用 persistentContainer,它可以帮助您设置核心数据堆栈。 persistentContainer 有两种类型的上下文:viewContextbackground contexts

对于此设置,我们总是使用 viewContext 获取数据以显示在 UI 上。 并使用 background context 进行更改、更新存储...

  1. 您在 init 方法中传递的上下文类型是什么?
  2. 您应该在您用于进行更改的上下文(您传递给 init)上执行 context.save()。在这种情况下,您不应将 viewContext 传递给 init 并使用 viewContext 调用 save()
  3. 如何在多个 ViewController 之间更新和同步更改? 进行更改的视图控制器也应该调用保存。您可以使用 delegation 模式 delegate/broadcast 更改其他视图控制器...