Core Data сохраняет дочерний контекст в PerformBlock: удаляет стек отмены

Я делаю приложение для рисования. При каждом касании создаются некоторые основные объекты данных. Пользователь может нажать кнопку отмены, и эти клики будут отменены по одному. Это прекрасно работает.

Проблема возникает, когда запускается какая-то автоматизированная задача. У меня есть кнопка, которая создает набор основных объектов данных (рисует некоторые вещи сама по себе) в дочернем контексте, а затем сохраняет контекст, чтобы изменения отражались в основном контексте.

Проблема в том, что не имеет значения, сколько раз пользователь нажимает кнопку задачи, все изменения группируются в один шаг отмены.

Чтобы было понятно: он выполняет 5 задач, а затем один раз нажимает кнопку «Отменить» и возвращается к началу. Но я хочу, чтобы он мог отменить каждую задачу по одной.

Я использую UIManagedDocument и его стек основных данных. Итак, это 2 контекста: один для записи на диск и его дочерний элемент для общего использования, а затем я создаю дочерний элемент последнего для фоновых операций.

Это мой код:

NSManagedObjectContext* childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
childContext.parentContext = self.document.managedObjectContext;
childContext.undoManager = self.document.undoManager;
[childContext performBlock:^{

    //a lot of things happen here, that generate many entities

    [childContext save:nil];

    [self.document.managedObjectContext performBlock:^{

        //completion stuff, update UI...

    }];
}];

person Odrakir    schedule 15.03.2013    source источник


Ответы (1)


Одна из идей состоит в том, чтобы заключить каждый блок кода, который вы хотите отменить, в отдельный блок (с тем же дочерним контекстом). Может быть, начать разбивать его на две части и посмотреть, сработает ли это.

Если подумать, я думаю, что каждое сохранение на самом деле не сохраняет, а просто передает изменения в родительский контекст. Итак, я предполагаю, что родительский контекст регистрирует каждое дочернее сохранение как одно событие, которое невозможно выполнить. Может быть, вы могли бы попробовать сохраняться чаще, а затем посмотреть, можно ли отменить эти фрагменты.

person Mundi    schedule 15.03.2013
comment
То, что вы описываете, - это именно то, что я хочу: каждое сохранение дочернего контекста должно быть одним невыполнимым событием. Но это так не работает. С каждым дочерним сохранением он группирует все предыдущие операции в одно событие, которое невозможно выполнить, оставляя документ таким, каким он был при открытии. - person Odrakir; 16.03.2013
comment
Так? Вы пробовали первую стратегию с созданием отдельных контекстов? - person Mundi; 16.03.2013
comment
Если я правильно вас понял, я этим и занимаюсь. Каждый блок кода, который я хочу отменить, находится внутри собственной функции PerformBlock. Это не работает. - person Odrakir; 18.03.2013
comment
Вы пробовали выделять разные контексты? Просто любопытно. - person Mundi; 18.03.2013
comment
Извините, я не думаю, что понимаю вас. Существует основной контекст UIManagedDocument (self.document.managedObjectContext), а затем дочерний контекст, который я создаю в опубликованном коде. - person Odrakir; 18.03.2013
comment
Да, моя идея состояла в том, чтобы создать более одного дочернего контекста, по одному для каждого желаемого шага отмены. - person Mundi; 18.03.2013
comment
Я делаю это. Дочерний контекст создается каждый раз, когда пользователь выполняет одну из этих задач, поэтому каждый раз это другой контекст. - person Odrakir; 19.03.2013