これはイベントが進行する順序の単なる例であり、実際の例ではないと思います.
たまたま、ManagedObjectContext に NSUndoManager を与えるのを忘れていませんか?
OS X ではデフォルトで 1 つ取得できると思いますが、iOS では特に指定する必要があります。
MOC を作成するときは、必ず元に戻すマネージャーを設定する必要があります...
managedObjectContext.undoManager = [[NSUndoManager alloc] init];
undo-manager が nil の場合、これを行った後、複数の MOC を使用しているか、他のコードによってリセットされています。
また、デバッグのために、appoint.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");
}
編集
管理対象オブジェクトの MOC は、いくつかの条件下で nil に設定できます。たとえば、オブジェクトを削除してから mod を保存すると、そのオブジェクトの MOC は nil に設定されます...
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:@"SomeEntity" inManagedObjectContext:moc];
[object.managedObjectContext deleteObject:object];
[moc save:0];
// object.managedObjectContext will be nil
もう 1 つのあまり一般的ではないケースですが、MOC にメモリの問題がある可能性を示す兆候です... ARC では、管理対象オブジェクトの MOC は弱いポインターです。したがって、MOC がなくなると、そのポインターは nil にリセットされます。非 ARC では、ポインターは古い値を持つだけで、結果は未定義になります...おそらくクラッシュします。
したがって、managedObject.managedObjectManager が nil の場合、最も可能性の高い原因は次のとおりです。
- オブジェクトは MOC に挿入されませんでした
- オブジェクトは MOC から削除されました
- MOC が削除されました