将关系插入核心数据的正确方法

时间:2017-01-17 17:01:34

标签: ios swift core-data

我有这个核心数据模型:

enter image description here

有时,当我尝试插入“BoissonCave”元素时,我的应用程序崩溃了。这就是它发生的地方(我正在从包含JSON数据的数组“values”中读取数据):

let boissonCave = BoissonCave(context: context)
[...]
if let _regionId = values["regionId"] as? Int16 {
    let region = CoreDataStack.sharedInstance.getRegion(ofId: Int(_regionId))
    boissonCave.fromRegion = region
}

当Core Data获取“Region”时,或者当我尝试从boissonCave的fromRegion中分配时,我会遇到不同的错误。它要么是

EXC_BAD_ACCESS

'NSInvalidArgumentException', reason: '-[__NSCFSet addObject:]: attempt to insert nil'

甚至*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSCFSet: 0x174259c80> was mutated while being enumerated.'

我怀疑这是一个上下文问题,Core Data试图在一个上下文中获取一个Region,并在另一个上下文中插入一个BoissonCave?我该怎么解决这个问题?

2 个答案:

答案 0 :(得分:0)

基于CoreDataStack。为什么不使用1个静态核心数据堆栈?并在需要时创建子上下文。您始终可以将对子项的更改合并到主上下文中。这是我自iOS 10.0以来使用的url上的一个非常轻微的修改版本

class CoreDataStack {

    static let shared = CoreDataStack()

    lazy var persistentContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name: "Almanapp")
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error {
                fatalError("Unresolved error \(error)")
            }
        })
        return container
    }()

    var context : NSManagedObjectContext {
        return self.persistentContainer.viewContext
    }

    func saveContext() {
        let context = persistentContainer.viewContext
        if context.hasChanges {
            do {
                try context.save()
            } catch let error as NSError {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        }
    } 
}

答案 1 :(得分:0)

那么诀窍是两件事的组合:

- 首先,我确保通过在SousRegion之间包装插入代码,在我的BoissonCave对象之前插入了context.performAndWait { ... }lazy var viewContext: NSManagedObjectContext = { self.persistentContainer.viewContext.mergePolicy = NSMergePolicy.mergeByPropertyObjectTrump self.persistentContainer.viewContext.automaticallyMergesChangesFromParent = true try! self.persistentContainer.viewContext.setQueryGenerationFrom(.current) return self.persistentContainer.viewContext }() 个对象(当然,你必须这样做)对两个插入使用相同的上下文)

- 我在我的上下文中添加了合并政策:

public function togglePublish($id)
{
    $publish = Books::find($id);

    if ($publish->published === 1) {
        $publish->published = 0;
    } else {
        $publish->published = 1;
    }

    $publish->save();
    return redirect()->route('book');
}

从那以后我没有崩溃。