2

RestKit で作成した «Picture» という名前の NSManagedObject があるとします。NSOperation を介して実際の画像ファイルのコンテンツをアップロードしています。その NSOperation はアップロードの進行状況を追跡し、Picture オブジェクトの «progress» 属性に保存します。

if(![self isCancelled]) {
    Picture *pic = [Picture findFirstByAttribute:@"pictureId" withValue:self.pictureId];
    if(![pic isDeleted]) {
        pic.progress = [NSNumber numberWithFloat:progress];
        [[RKObjectManager sharedManager].objectStore save:NULL];
    }
}

私のView Controllerは、NSFetchedResultsControllerの助けを借りて、Pictureオブジェクトのリストを表示しています。アップロードはうまく機能し、RestKit はスレッド セーフを実行し、メインの NSManagedObjectContext にマージして戻すため、UI はアップロードの進行状況を期待どおりに表示しています。

画像をアップロードしているときに、ユーザーが «cancel» 十字キーを押すと、Picture オブジェクトも削除されると想像してください。コントローラーでは、NSOperation でキャンセルを呼び出しています。これにより、操作の実行が数ミリ秒以内に効果的に停止し、メイン スレッドで CoreData からオブジェクトが削除されます。

[uploadOperation cancel];
Picture *pic = [Picture findFirstByAttribute:@"pictureId" withValue:self.pictureId];
[pic deleteEntity];
[[RKObjectManager sharedManager].objectStore save:NULL];

トレースは、予想どおり NSFetchedResultsControllerDelegate で NSFetchedResultsChangeDelete を取得したことを示しています。ただし、進行状況の保存は NSOperation によって非常に頻繁に行われるため、その直後に NSFetchedResultsChangeInsert と NSFetchedResultsChangeUpdate が続きます。NSOperation で使用される NSManagedObjectContext が同期していないようです。Picture オブジェクトが削除されたことを認識していないため、save: の呼び出しによって挿入と更新が行われます。

したがって、私の UI (および DB) では、Picture オブジェクトは削除されるはずなのに残ります。

RKManagedObjectStore を見ると、バックグラウンド スレッド (NSOperation) からメイン スレッド (ビュー コントローラー) へのマージが行われているように見えますが、その逆ではないようです。

この問題を解決する最善の方法は何ですか?

4

2 に答える 2

0

おそらくアプリの制御フローを少し変更する必要があると思います。NSOperation がまだ進行中のときにメイン コンテキストでオブジェクトを削除することは、悪い考えのように思えます。たとえば、操作自体がキャンセルされたかどうかを確認し、NSOperationその MOC を使用してそこから画像オブジェクトを削除してみませんか? そのようにして、1 つの子 MOC にのみ書き込みを行います。別の方法、つまり、すべての変更の前に操作で子 MOC を更新すると、個別のコンテキストを持つという目的が無効になります。

それについて考えるNSManagedObjectContextObjectsDidChangeNotificationと、適切な を観察してマージする賢い方法があるかもしれませんNSMergePolicyが、繰り返しになりますが、それはあなたのケースではやり過ぎだと思います。キャンセルと削除全体を同じ場所で処理するだけです。

于 2013-06-03T19:56:47.887 に答える
0

Core Data Undo Manager を使用するのに最適な状況のように思えます。ここまたは Apple が提供する CoreDataBooks Example で良い例を見つけることができます。

于 2012-11-19T21:11:29.957 に答える