MagicalRecord saveWithBlock vs saveToPersistentStoreAndWait

时间:2014-06-16 19:05:10

标签: ios iphone core-data nsmanagedobjectcontext magicalrecord

我正在努力理解MagicalRecord和CoreData的所有内容。所以说,我有2段代码做同样的事情,其中​​tallyM是在MR_defaultContext中运行的托管对象。

选项1:

Tally *tallyM                       = (Tally *)[Tally MR_findFirstWithPredicate:predicateM];

[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {

    Tally *tallyMLocal              = [tallyM MR_inContext:localContext];
    tallyMLocal.tl_countMale        = [NSString stringWithFormat:@"%ld", (long)uiTallyMaleCounter];

} completion:^(BOOL success, NSError *error) {

        [self updateTallies_APICall:[tallyM MR_inContext:[NSManagedObjectContext MR_defaultContext]]];
}];

选项2:

Tally *tallyM                       = (Tally *)[Tally MR_findFirstWithPredicate:predicateM];
tallyM.tl_countMale                 = [NSString stringWithFormat:@"%ld", (long)uiTallyMaleCounter];
[tallyM.managedObjectContext MR_saveToPersistentStoreAndWait];
[self updateTallies_APICall:[tallyM MR_inContext:[NSManagedObjectContext MR_defaultContext]]];

问题:

  1. 哪一个更好?我知道当你需要异步保存时可以使用saveWithBlock,但还有其他区别吗? 选项1 是否比选项2 更安全或更好?

  2. 选项1 中,我有一个在MR_defaultContext中运行的tallyM。然后在saveWithBlock中,我通过更改tallyMLocal和保存上下文来更改tallyM。我可以100%确定在saveWithBlock运行之后,在完成处理程序中(当我需要继续使用tallyM时),tallyM(仍然在MR_defaultContext中运行)将更新tl​​_countMale吗?

  3. 选项1 中,在完成处理程序中,是否仍需要调用以下代码?我假设(已经通过控制台检查,但只是想确定)在执行saveWithBlock之后,tallyM仍在MR_defaultContext中运行。那么需要再次调用MR_inContext吗?

    [tallyM MR_inContext:[NSManagedObjectContext MR_defaultContext]]

  4. 假设我根本不需要异步保存。所以我可以使用选项2 saveWithBlockAndWait saveWithBlockAndWait 是否比选项2 更好?

  5. 我只是想确保我最终正确理解了MagicalRecords和CoreData的行为。

1 个答案:

答案 0 :(得分:3)

就个人而言,我会避免选项2中的模式。我们的想法是,您应该使用单个托管对象上下文作为托管对象集合上的操作范围。这就是为什么大多数示例使用以下模式:

NSManagedObjectContext *localContext = //...;
NSManagedObject *localObject = [otherObject MR_inContext:localContext];
///make changes to localObject
[localContext MR_saveToPersistentStoreAndWait];

[MagicalRecord saveWithBlock:]方法基本上在更方便的API中实现了这种模式。

我还建议不要隐式使用defaultContext。在您的代码中更明确地说明这一点,因为当您的应用程序开始处理线程时,您可能需要将其交换出来。

完成处理程序的编写方式是在保存操作完成100%后始终回调它们。我建议您阅读源代码以便自己查看。

相关问题