Что касается MagicalRecord, в чем разница между методами MR_saveNestedContexts и MR_save?

В документации MagicalRecord на github указано:

MagicalRecord предоставляет очередь фонового сохранения, так что сохранение всех данных выполняется вне основного потока в фоновом режиме. Это означает, что может быть необходимо использовать MR_saveNestedContexts, а не типичный метод MR_save, чтобы сохранить ваши изменения на всем пути к вашему постоянному хранилищу.

глядя на источник, я не могу понять разницу между этими двумя методами без команды dispatch_async. Я вижу, что они оба сохраняют все вложенные контексты до корня, поэтому сохраняются в хранилище. Но почему и в какой ситуации я бы использовал один вместо другого?

Кроме того, поскольку я просто сохраняю вложенный контекст на один уровень выше (без сохранения для сохранения), я предполагаю, что все равно буду использовать метод - (BOOL)save:(NSError **)error NSManagedObjectContext?

Ниже приведен исходный код двух методов.

- (void) MR_save {
    [self MR_saveErrorHandler:nil];
}

- (void) MR_saveErrorHandler:(void (^)(NSError *))errorCallback {
    [self performBlockAndWait:^{
        [self MR_saveWithErrorCallback:errorCallback];

        if (self.parentContext) {
            [[self parentContext] performBlockAndWait:^{
                [[self parentContext] MR_saveErrorHandler:errorCallback];
            }];
        }
    }];
}

- (void) MR_saveNestedContexts {
    [self MR_saveNestedContextsErrorHandler:nil];
}

- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback {
    [self MR_saveNestedContextsErrorHandler:nil completion:nil];
}

- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback completion:(void (^)(void))completion {
    [self performBlock:^{
        [self MR_saveWithErrorCallback:errorCallback];

        if (self.parentContext) {
            [[self parentContext] performBlock:^{
                [[self parentContext] MR_saveNestedContextsErrorHandler:errorCallback completion:completion];
            }];
        } else {
            if (completion) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    completion();
                });
            }
        }
    }];
}

person Gobot    schedule 09.11.2012    source источник


Ответы (2)


С новой функцией Parent/Child в CoreData, начиная с iOS5 и Lion, иногда необходимо «принудительно» сохранять все данные на диск. То есть, когда у вас есть, например, 3 контекста, такие как:

root <- child1 <- child2

Если вы сохраняете в дочернем2, эти изменения будут уведомлены только на один уровень до дочернего1. У рута их не будет. Чтобы сделать это, вы должны вызвать save еще раз. Тот факт, что у вас может быть произвольно длинный список этих контекстов, означает, что вы не будете знать, доберется ли ваше сохранение до корневого контекста, который также отвечает за сохранение изменений в хранилище (диске). saveNestedContexts использует рекурсию, чтобы пройти по этому дереву и убедиться, что ваше сохранение действительно попадает на диск, когда вы намеревались это сделать.

person casademora    schedule 09.11.2012
comment
Правильно, но из исходного кода оба метода рекурсивно доходят до корня через if (self.parentContext) {... и сохраняют через [self MR_saveWithErrorCallback:errorCallback];. Так что похоже, что MR_save делает то же самое. - person Gobot; 09.11.2012

Сходство между MR_save и MR_saveNestedContexts было изменено в версии 2.0.8 (я использовал 2.0.7).

Вот коммит на github: https://github.com/magicalpanda/MagicalRecord/commit/f7c4350e9daf7d90eec83ba343eafeccfa27< /а>

И обсуждение: https://github.com/magicalpanda/MagicalRecord/issues/305

Таким образом, в версии 2.0.8 MR_save теперь сохраняет только текущий контекст, а MR_saveNestedContexts рекурсивно сохраняет до самого верхнего контекста.

person Gobot    schedule 12.11.2012
comment
На самом деле это не так просто. MR_save ждал завершения сохранения. MR_saveNestedContexts является полностью асинхронным и возвращается немедленно. Так что они не совсем дубликаты. См.: github.com/magicalpanda/MagicalRecord/issues/318. - person batkuip; 26.11.2012