У меня проблема с NSUndoManager, который не удаляется при работе со сложной моделью.
Это моя модель.
У меня есть Singleton, который заботится о ядре данных, это его инициализация:
model =[NSManagedObjectModel mergedModelFromBundles:nil];
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
NSString *path = pathInDocumentDirectory(@"store.data");
NSURL *storeURL = [NSURL fileURLWithPath:path];
NSError *error = nil;
if(![psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeURL
options:nil
error:&error]) {
[NSException raise:@"Open failed" format:@"Reason: %@", [error localizedDescription]];
}
context = [[NSManagedObjectContext alloc] init];
NSUndoManager *contextUndoManager = [[NSUndoManager alloc] init];
[contextUndoManager setLevelsOfUndo:20];
[context setUndoManager:contextUndoManager];
[context setPersistentStoreCoordinator:psc];
Для каждой сущности у меня есть метод init, который вызывает [self initWithEntity ...] и затем вводит некоторые свойства. Это пример сущности HalfEdge:
- (id) initWithVertex:(Vertex*) vert inManagedObjectContext: context {
NSEntityDescription* tEntityDescription = [NSEntityDescription entityForName: @"HalfEdge"
inManagedObjectContext: context];
self = [self initWithEntity: tEntityDescription insertIntoManagedObjectContext: context];
if(self) {
self.lastVertex = vert;
[self.lastVertex addHalfEdgeObject:self];
}
return self;
}
Когда пользователь добавляет новый чертеж, я создаю новый объект Drawing и затем позволяю пользователю добавлять точки, прикоснувшись к экрану. Для каждой точки будет выполняться рутина, которая может добавлять и / или удалять треугольные объекты, половинки и вершины. Это вызов:
[[[DrawingsStore sharedStore].managedObjectContext undoManager] beginUndoGrouping];
[delaunay addPoint:CGPointMake(localizacion.x-dummy.bounds.size.width/2, localizacion.y-dummy.bounds.size.height/2)];
[[DrawingsStore sharedStore].managedObjectContext processPendingChanges];
[[[DrawingsStore sharedStore].managedObjectContext undoManager] endUndoGrouping];
Как видите, я установил группу отмены для всего, что происходит внутри этой рутины.
Затем, когда нажимается кнопка, я звоню [[context undoManager] undo]; но это ничего не делает.
Я печатаю выборку до и после отмены, и это то же самое. Я вижу, что рутин работает правильно, добавляя все правильные сущности в основные данные, но затем он вообще ничего не отменяет.
РЕДАКТИРОВАТЬ с предложениями от Aderstedt
Хорошо, я удалил пользовательский метод init для подклассов NSManagedObject и создал метод класса следующим образом:
+ (HalfEdge*) addWithVertex:(Vertex*) vert inManagedObjectContext: context {
HalfEdge* halfEdge = [NSEntityDescription insertNewObjectForEntityForName:@"HalfEdge" inManagedObjectContext:context];
if(halfEdge) {
halfEdge.lastVertex = vert;
[halfEdge.lastVertex addHalfEdgeObject:self];
}
return halfEdge;
}
И все тот же результат. Объекты создаются, отмена не работает. (canUndo возвращает 1)
EDIT
Ничего себе, я только что зарегистрировался для NSUndoManagerCheckpointNotification от undoManager, и как только я нажму кнопку отмены, он будет опубликован навсегда, как в цикле. Хорошо, теперь я знаю, что где-то что-то не так делаю, но ... где?