NSPersistentContainer的核心数据并发 [英] Core Data concurrency with NSPersistentContainer

查看:167
本文介绍了NSPersistentContainer的核心数据并发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:我看过类似的问题,但找不到描述这种情况的问题.

NOTE: I've looked at similar questons, but didn't find one that describes this situation.

我正在看苹果公司关于核心数据并发性的以下示例代码( https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/Concurrency.html )

I'm looking at the following example code from Apple regarding Core Data concurrency (https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/Concurrency.html)

NSArray *jsonArray = …;
NSPersistentContainer *container = self.persistentContainer;
[container performBackgroundTask:^(NSManagedObjectContext *context) {
    for (NSDictionary *jsonObject in jsonArray) {
        AAAEmployeeMO *mo = [[AAAEmployeeMO alloc] initWithContext:context];
        [mo populateFromJSON:jsonObject];
    }
    NSError *error = nil;
    if (![context save:&error]) {
        NSLog(@"Failure to save context: %@\n%@", [error localizedDescription], [error userInfo]);
        abort();
    }
}];

在我的应用中,只有在用户点击屏幕上的保存"按钮后,保存操作才会启动.在私有上下文是VC的属性的情况下,应该如何使用子上下文代替呢?

In my app, the save is not initiated until the user taps the save button on the screen. How do I go about it, should I use a child context instead for that situation, where the private context is a property of the VC?

NSArray *jsonArray = …; //JSON data to be imported into Core Data
NSManagedObjectContext *moc = self.persistentContainer.viewContext; //Our primary context on the main queue

NSManagedObjectContext *private = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[private setParentContext:moc];

[private performBlock:^{
    for (NSDictionary *jsonObject in jsonArray) {
        NSManagedObject *mo = …; // WHICH CONTEXT TO USE?  <<<======
        //update MO with data from the dictionary
    }
    NSError *error = nil;
    if (![private save:&error]) {
        NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]);
        abort();
    }
}

然后,当用户点击保存"时,请执行以下操作:

And then once the user taps save do this:

NSManagedObjectContext *moc = self.persistentContainer.viewContext; //Our primary context on the main queue
   [moc performBlockAndWait:^{
            NSError *error = nil;
            if (![moc save:&error]) {
                NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]);
                abort();
            }
        }];
    }];

还要注意在上面的示例中使用哪个moc的问题(<<< =====)

Also note the question which moc to use in the example above (<<<=====)

编辑:最后,我最后要做的就是立即保存子上下文,以便表仅使用viewContext来显示结果.如果用户随后退出但未保存,我将再次从viewContext中删除所有结果.保存按钮仍然存在,但现在仅设置一个标志,指示不删除结果.

What I ended up doing in the end is save the child context immediately so that the table only uses viewContext to display the results. If the user then exits without saving, I delete all the results again from the viewContext. The save button is still there, but now only sets a flag indicating not to delete the results.

推荐答案

如果您有一页表单,并且希望在用户按下保存"按钮时将其保存,则只需从textFields中获取数据(或其他任何内容)数据输入是),然后使用performBackgroundTask将其放入核心数据中.由于数据仅在用户编辑时存储在textFields中,如果用户回推,则其编辑将丢失.

If you have one page of forms and you want it to save when the user presses the save button, then simply take the data from the textFields (or whatever your data input is) and put it into core data using performBackgroundTask. Since the data is only stored in the textFields while the user is editing if the user pushes back his edits will be lost.

如果您对具有许多不同实体的复杂文档进行了很多更改,用户可以创建或销毁或链接这些实体,并且仅当用户按下保存时才保存所有这些内容,那么您应该使用子上下文.您将基于子上下文中的值显示数据,但只有在用户按保存时,才将这些更改推送到父上下文中.这是一种非常罕见的情况,我个人从未遇到过这样做的需要.

If you have a lots of changes to a complex document with lots of different entities that the user can create or destroy or link and all of that is only saved when the user presses save then you should use a child context. You would display the data based on the values in the child context but only push those changes to the parent context if the user presses save. This is a very rare situation and I have never personally encountered the need to do this.

我强烈怀疑您是第一种情况.不要使用子上下文.使用performBackgroundTask并在用户按保存时保存数据.

I strongly suspect that you are in the first case. Don't use child context. Use performBackgroundTask and save the data when the user presses save.

(在private块中使用的正确上下文也是private上下文)

(also the correct context to use inside the block [private performBlock:^{ is the private context)

这篇关于NSPersistentContainer的核心数据并发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆