【问题标题】:Coredata performBlock then return the new valueCoredata performBlock 然后返回新值
【发布时间】:2016-02-07 09:50:56
【问题描述】:

如果我使用performBlock 保存 managedObjectContext,如何返回 coredata 中保存的新对象?

要求是,在coredata中添加一个条目,并返回它。我的代码是这样的:

//create a privateMOC
NSManagedObjectContext *private = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];

//set parentContext
[private setParentContext:self.coredataManager.managedObjectContext];

__block Detail *object = nil;

[private performBlock:^{
    //fetch from the db
    object = [self.coredataManager insertObjectWithEntityName:NSStringFromClass([Detail class])];

    //save the private context
    NSError *error = nil;
    if (![private save:&error]) {
        NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]);
    }

}];

return object;

由于保存是在 Block 中进行的,因此将首先执行 return。但我需要具有最新值的object。请有任何建议。

【问题讨论】:

  • 您不想使用performBlockAndWait。它会导致调用线程阻塞,如果不小心处理,可能会导致死锁问题。一般来说,你应该避免performBlockAndWait,除非没有其他解决方案。我发现这非常罕见。此外,无论如何,您不能对要在另一个 performBlock 之外返回的对象执行任何操作,除非可能将其存放在某处以供以后参考。那么,为什么要退货呢?为什么不在performBlock 中做任何你想做的事情?
  • 新创建的值被传递到包括后台应用程序/进程在内的几个地方。
  • @JodyHagins:请看我的评论
  • 为什么不能从performBlock代码内部“传递到多个地方”?
  • 是的,但我的意思是您不需要返回任何东西。没有理由等待它完成并返回一些东西。您应该能够在该块内做您想做的事情。

标签: ios objective-c core-data nsmanagedobjectcontext nsthread


【解决方案1】:

而不是返回新创建的Core Data对象,向构造方法传递一个带有你正在创建的对象类型参数的块。

在托管对象上下文的performBlock: 块中创建对象后,调用您的completion 块并传入新构造的核心数据对象。

+ (void)coreDataObjectWithJSON:(NSDictionary *)json completion:(void (^)(NSYourCoreDataObject *coreDataObject))completion {

    [yourManagedObjectContext performBlock:^{

        NSEntityDescription *entity = [NSEntityDescription entityForName:... inManagedObjectContext:...];

        NSYourCoreDataObject *coreDataObject = [[NSYourCoreDataObject alloc] initWithEntity:entity insertIntoManagedObjectContext:...];

        if (completion) {
            // "return" the new managed object
            completion(coreDataObject);
        }
    }];
}

【讨论】:

    【解决方案2】:

    我做了一些研究,发现解决这个问题并不难:

    我用performBlockAndWait 替换了performBlock,它成功了。

    原因很简单:performBlock 是异步的,而 performBlockAndWait 是同步的。

    【讨论】:

    • 请记住它是阻塞的,并且您将其返回链接到一个临时上下文,因此您需要注意仅在该上下文中访问它(实际上没有人看起来拥有... )
    • performAndWait 不仅仅是 perform 的同步版本。它也有操作顺序的差异。见stackoverflow.com/a/32214574/354876
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    • 2019-08-05
    • 2018-09-26
    • 2020-09-24
    相关资源
    最近更新 更多