Bot*_*Bot 2 core-data objective-c nsundomanager ios5
我有一个NSManagedObject调用appointment,我编辑的属性.如果我用户按下取消,我想要撤销所有这些编辑.
如果我这样做(示例代码)
[[appointment managedObjectContext] setUndoManager:[[NSUndoManager alloc] init]]; //however doing a nslog on undoManager still shows it as (null);
[[[appointment managedObjectContext] undoManager] beginUndoGrouping];
appointment.startTime = 11;
appointment.endTime = 12;
appointment.customer = @"Tom";
[[[appointment managedObjectContext] undoManager] endUndoGrouping];
[[[appointment managedObjectContext] undoManager] undo];
Run Code Online (Sandbox Code Playgroud)
不应该撤消之间的所有变化beginUndoGrouping和endUndoGrouping?似乎有很多方法可以做到这一点,但我似乎无法找到正确的方法.撤消更改的正确方法是NSManagedObject什么?
我想这只是事件发生顺序的一个例子,而不是一个实际的例子.
你偶然忘了给ManagedObjectContext一个NSUndoManager吗?
我相信你在OS X下默认获得一个,但在iOS下,你必须专门提供一个.
您希望确保在创建MOC时设置撤消管理器...
managedObjectContext.undoManager = [[NSUndoManager alloc] init];
Run Code Online (Sandbox Code Playgroud)
如果undo-manager为nil,那么在执行此操作后,您将使用多个MOC,或者其他一些代码已重置它.
此外,出于调试目的,请检查appointment.managedObjectContext属性,并确保它不是nil并引用有效的MOC.
编辑
好吧,我刚刚使用一个简单的模型去写了一个快速测试.也许你应该做类似的事情,看看你的断言失败的地方(你可以在你的代码路径中添加正常的断言 - 我做了一个作为单元测试,所以我可以轻松地将它添加到现有项目).
- (void)testUndoManager
{
NSDate *now = [NSDate date];
NSManagedObjectContext *moc = [self managedObjectContextWithConcurrencyType:NSConfinementConcurrencyType];
STAssertNil(moc.undoManager, @"undoManager is nil by default in iOS");
moc.undoManager = [[NSUndoManager alloc] init];
[moc.undoManager beginUndoGrouping];
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:EVENT_ENTITY_NAME inManagedObjectContext:moc];
STAssertNotNil(moc, @"Managed Object is nil");
STAssertEquals(moc, object.managedObjectContext, @"MOC of object should be same as MOC");
STAssertNotNil(object.managedObjectContext.undoManager, @"undoManager of MOC should not be nil");
[object setValue:now forKey:@"timestamp"];
STAssertEqualObjects(now, [object valueForKey:@"timestamp"], @"Timestamp should be NOW");
[moc.undoManager endUndoGrouping];
STAssertEqualObjects(now, [object valueForKey:@"timestamp"], @"Timestamp should be NOW");
[moc.undoManager undo];
STAssertNil([object valueForKey:@"timestamp"], @"Object access should be nil because changes were undone");
}
Run Code Online (Sandbox Code Playgroud)
编辑
在几个条件下,托管对象的MOC可以设置为nil.例如,如果删除对象,然后保存mod,则该对象的MOC将设置为nil ...
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:@"SomeEntity" inManagedObjectContext:moc];
[object.managedObjectContext deleteObject:object];
[moc save:0];
// object.managedObjectContext will be nil
Run Code Online (Sandbox Code Playgroud)
另一个不太常见的情况,但有迹象表明MOC可能存在内存问题......在ARC下,托管对象的MOC是弱指针.因此,如果MOC消失,该指针将被重置为nil.在非ARC下,指针只有旧值,结果将是未定义的...可能是崩溃.
因此,如果managedObject.managedObjectManager为nil,最可能的罪魁祸首是: