2011-11-15 19 views
0

複雑なモデルで作業するときにNSUndoManagerが元に戻すことができないという問題があります。NSUndoManagerがiOSのコアデータで作業を取り消します

これは私のモデルです。

core data model

私はコアデータのものの世話をするシングルトンを持って、これはその初期化です:私は[自己initWithEntityを呼び出すinitメソッドを持っているすべてのエンティティのために

 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]; 

...いくつかのプロパティを挿入します。

- (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; 
} 

ユーザーが、私は新しい図面エンティティを作成し、ユーザが画面をテーピングポイントを追加してみましょう新しい図面を追加します。これはHalfEdge実体の一例です。すべての点について、三角形のエンティティ、ハーフジッジおよび頂点を追加および/または削除するルチンが実行されます。これはコールです:

[[[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

からsugestionsと

EDITは[OK]を、私はNSManagedObjectのサブクラス用のカスタムinitメソッドを削除し、このようなクラスメソッドを作成:

+ (HalfEdge*) addWithVertex:(Vertex*) vert inManagedObjectContext: context { 

    HalfEdge* halfEdge = [NSEntityDescription insertNewObjectForEntityForName:@"HalfEdge" inManagedObjectContext:context]; 

    if(halfEdge) { 
     halfEdge.lastVertex = vert; 
     [halfEdge.lastVertex addHalfEdgeObject:self]; 
    } 

    return halfEdge; 
} 

そして、まだ同じ結果を。オブジェクトが作成され、取り消しが機能しません。

EDIT(canUndoは1を返します)

うわー、私はちょうどundoManagerのNSUndoManagerCheckpointNotificationのために登録して、私はそれがループのように永遠に掲載されます元に戻す]をクリックすると。さて、私はどこかに間違ったことをしているに違いないと知っていますが、どこで?

答えて

2

私は知っていました。私は間違った場所で探していたことが分かります。

NSUndoManagerをデバッグしようとしました。通知用に登録して、NSUndoManagerCheckpointNotificationが何度も繰り返し呼び出されていることがわかりました。

[delaunay addPoint ...]モデルのすべての変更を行います。しかし同時に、三角形をレンダリングするレンダリングルーチンが画面に表示されます。そのルーチンでは、それらの三角形の色を設定します。私はスクリーンの背景をレンダリングする前に置くべき色を知らないので、そこで行う必要があります。

NSManagedObjectサブクラスTriangleの色属性を変更すると、NSUndoManagerCheckpointNotificationが発生し、取り消しが機能しなくなりました。それを取り除くと元に戻すことができます。

これを追加するだけでよいので、レンダリング中に加えられた変更は、元に戻すスタックには反映されません。

[[[DibujosStore sharedStore] managedObjectContext] processPendingChanges]; 
[[[[DibujosStore sharedStore] managedObjectContext] undoManager] disableUndoRegistration]; 
[renderer render]; 
[[[DibujosStore sharedStore] managedObjectContext] processPendingChanges];   
[[[[DibujosStore sharedStore] managedObjectContext] undoManager] enableUndoRegistration]; 
-1

NSManagedObjectインスタンスを作成していますWrong Way™。

- [NSEntityDescription insertNewObjectForEntityForName:... inManagedObjectContext...] 

新しいオブジェクトを挿入する。あなたはそれが挿入されたときのオブジェクトのカスタム処理を行いたい場合は、あなたのNSManagedObjectサブクラスで

- (void)awakeFromInsert 

をオーバーライドします。 initWithEntity...を無効にすることをお勧めしません。あなたの元に戻す問題については、

[delaunay addPoint:CGPointMake(localizacion.x-dummy.bounds.size.width/2, localizacion.y-dummy.bounds.size.height/2)]; 

...を呼び出しても実際にCore Dataオブジェクトの属性が変更されますか?他のインスタンス変数、キャッシュされた配列など元に戻すために自動的に登録されません。コアデータオブジェクトの属性を変更する場合は、[context undoManager]がnilでないことを確認してください。

+0

お返事ありがとうございます。私はあなたの言うことを試みます。 NSManagedObjectのサブクラス化に関するドキュメントを読んだところ、実際にはinitWithEntityをオーバーライドしているわけではありませんが、これを行うにはあまりにも正しいとは思われませんが、実際にはどこかに見えましたエンティティが作成され、コアデータデータベースに追加されていると私は言っています。 awakeFromInsertについては、イニシャライザにいくつかのパラメータを渡す方法はありますか? – Odrakir

+0

'-insertNewObjectForEntityForName'は挿入されたオブジェクトを返します。これを使用していくつかの初期パラメータを設定できます。 – Aderstedt

+0

私はあなたが甘やかす方法を編集しました(上記参照)。まだ元に戻すことはできません。 – Odrakir

関連する問題