Ios MagicalRecord saveWithBlock vs SaveToPersistentStore并等待

Ios MagicalRecord saveWithBlock vs SaveToPersistentStore并等待,ios,iphone,core-data,nsmanagedobjectcontext,magicalrecord,Ios,Iphone,Core Data,Nsmanagedobjectcontext,Magicalrecord,我正在努力理解MagicalRecord和CoreData的一切。比方说,我有两段代码做同样的事情,其中tallyM是在MR_defaultContext中运行的托管对象 选项1: Tally *tallyM = (Tally *)[Tally MR_findFirstWithPredicate:predicateM]; [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localConte

我正在努力理解MagicalRecord和CoreData的一切。比方说,我有两段代码做同样的事情,其中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]]];
}];
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]]];
选项2:

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]]];
}];
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]]];
问题:

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]]];
}];
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]]];
  • 哪一个更好?我知道当您需要异步保存时,可以使用saveWithBlock,但还有其他区别吗?选项1在任何方面是否比选项2更安全或更好

  • 在选项1中,我有在MR_defaultContext中运行的tallyM。然后在saveWithBlock中,我通过更改tallyMLocal和保存上下文来更改tallyM。我是否可以100%确定在saveWithBlock运行后,在完成处理程序中(当我需要继续使用tallyM时),tallyM(仍在MR_defaultContext中运行)将更新tl_countMale

  • 在选项1中,在完成处理程序中,我还需要调用下面的代码吗?我假设(已经通过console检查过,但只是想确定)在执行saveWithBlock之后,tallyM仍然在MR_defaultContext中运行。那么有必要再打电话给吴先生吗

    [tallyM MR_inContext:[NSManagedObjectContext MR_defaultContext]]

  • 假设我根本不需要异步保存。因此,我可以使用选项2,或使用blockandwait保存。用blockandwait保存是否比选项2更好


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

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

    NSManagedObjectContext *localContext = //...;
    NSManagedObject *localObject = [otherObject MR_inContext:localContext];
    ///make changes to localObject
    [localContext MR_saveToPersistentStoreAndWait];
    
    [MagicalRecord saveWithBlock:]方法基本上在一个更方便的API中实现了这个模式

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

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