【问题标题】:Coredata CRUD operations in background thread?后台线程中的Coredata CRUD操作?
【发布时间】:2017-10-23 18:38:19
【问题描述】:

我在我的应用程序中使用来自苹果的以下代码 sn-ps 创建/更新 NSManagedObject

dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // Add code here to do background processing
    //
    //

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

        [private performBlock:^{
            for (NSDictionary *jsonObject in jsonArray) {
                NSManagedObject *mo = …; //Managed object that matches the incoming JSON structure
                //update MO with data from the dictionary
            }
            NSError *error = nil;
            if (![private save:&error]) {
                NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]);
                abort();
            }
            [mainMoc performBlockAndWait:^{
                NSError *error = nil;
                if (![mainMoc save:&error]) {
                    NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]);
                    abort();
                }
            }];
        }];




    dispatch_async( dispatch_get_main_queue(), ^{
        // Add code here to update the UI/send notifications based on the
        // results of the background processing
    });
});

我有两个疑问

  1. 仅使用上面的代码从我的模型中读取值,

    [private performBlock:^{}); 必填?

  2. 对于后台线程中的创建/更新 操作是否有更好的方法。我是否使用了上述操作的最佳方法?

提前致谢

【问题讨论】:

    标签: objective-c core-data nsmanagedobject nsmanagedobjectcontext


    【解决方案1】:

    来自 Apple 的文档Concurrency

    performBlock:performBlockAndWait: 确保块操作在为上下文指定的队列上执行。 performBlock: 方法立即返回,上下文在它自己的线程上执行块方法。使用performBlockAndWait: 方法,上下文仍然在自己的线程上执行块方法,但方法在块执行之前不会返回。

    当您使用NSPrivateQueueConcurrencyType 时,上下文会创建并管理一个私有队列。

    因此,如果您使用performBlock:,则无需创建另一个调度队列,因为它在块内异步执行操作。否则,如果你使用 performBlockAndWait: 等待直到完成它的操作执行,在这种情况下你应该使用另一个调度队列。

    因此,最佳做法是避免使用另一个调度队列。例如

    NSManagedObjectContext *private = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [private setParentContext:mainMoc];
    
    [private performBlock:^{
        for (NSDictionary *jsonObject in jsonArray) {
            NSManagedObject *mo = …; //Managed object that matches the incoming JSON structure
            //update MO with data from the dictionary
        }
        NSError *error = nil;
        if (![private save:&error]) {
            NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]);
            abort();
        }
        [mainMoc performBlockAndWait:^{
            NSError *error = nil;
            if (![mainMoc save:&error]) {
                NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]);
                abort();
            }
        }];
    }]; 
    

    【讨论】:

    • 非常感谢。在我的项目中,我已经在调度队列中实现了 performBlock。会不会出问题。我需要在所有地方都更改它吗?
    • 这不会产生任何问题,除非您在不同的线程或队列上使用私有并发上下文对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-12
    • 1970-01-01
    • 2021-10-19
    • 2013-06-13
    相关资源
    最近更新 更多