web-dev-qa-db-ja.com

「NSManagedObject」が削除されたかどうかを確認するにはどうすればよいですか?

削除されたNSManagedObjectがあり、その管理対象オブジェクトを含むコンテキストが保存されました。 Core Dataが永続ストアに次の保存操作中にオブジェクトを削除するよう要求する場合、isDeletedYESを返すことを理解しています。ただし、保存はすでに行われているため、isDeletedNOを返します。

NSManagedObjectが削除されたかどうかを判断する良い方法は何ですかafter含まれるコンテキストが保存されましたか?

(削除された管理対象オブジェクトを参照しているオブジェクトがなぜ削除を認識していないのか疑問に思っている場合は、削除とコンテキストの保存がperformSelectorOnMainThread:withObject:waitUntilDone:を使用して削除と保存を実行するバックグラウンドスレッドによって開始されたためです)

67

管理対象オブジェクトのコンテキストの確認は機能しているようです:

if (managedObject.managedObjectContext == nil) {
    // Assume that the managed object has been deleted.
}

managedObjectContextに関するAppleのドキュメントより...

このメソッドは、レシーバがそのコンテキストから削除された場合、nilを返す場合があります。

レシーバーに障害がある場合、このメソッドを呼び出してもレシーバーは起動しません。

どちらも良いことのようです。

UPDATE:objectWithID:を使用して具体的に取得した管理対象オブジェクトが削除されたかどうかをテストする場合は、チェックアウト Daveギャラガーの答え 。彼は、削除されたオブジェクトのIDを使用してobjectWithID:を呼び出すと、返されるオブジェクトはnotmanagedObjectContextがnilに設定されていることを指摘しています。したがって、そのmanagedObjectContextを単純にチェックして、削除されたかどうかをテストすることはできません。可能であればexistingObjectWithID:error:を使用します。そうでない場合、たとえば、Mac OS 10.5またはiOS 2.0をターゲットにしている場合は、削除をテストするために何か他のことをする必要があります。詳細については his answer をご覧ください。

90

他の回答の議論が実際に正しい答えの単純さを隠しているのではないかと心配しています。ほとんどすべての場合、正しい答えは次のとおりです。

if ([moc existingObjectWithID:object.objectID error:NULL])
{
    // object is valid, go ahead and use it
}

この回答が当てはまらない唯一のケースは次のとおりです。

  1. Mac OS 10.5以前をターゲットにしている場合
  2. IOS 2.0以前をターゲットにしている場合
  3. オブジェクト/コンテキストがまだ保存されていない場合(この場合、NSObjectInaccessibleExceptionをスローしないため気にしないか、object.isDeleted
27
JosephH

永続性のためにCore Dataに依存するiOSアプリでiCloudを実装した最近の経験により、フレームワークの通知を観察するのが最善の方法であることに気付きました。少なくとも、一部の管理対象オブジェクトが削除されたかどうかを通知する、または通知しない可能性のあるいくつかのあいまいなメソッドに依存するよりも優れています。

「純粋な」コアデータアプリの場合、メインスレッドでNSManagedObjectContextObjectsDidChangeNotificationを確認する必要があります。通知のユーザー情報ディクショナリには、管理オブジェクトの挿入、削除、更新されたオブジェクトIDのセットが含まれています。

これらのセットのいずれかで管理対象オブジェクトのobjectIDが見つかった場合、何らかの素敵な方法でアプリケーションとUIを更新できます。

それだけです...詳細については、Appleのコアデータプログラミングガイド、コアデータとの同時実行の章を参照してください。 「通知を使用して他のスレッドの変更を追跡する」セクションがありますが、前の「スレッド制限を使用して同時実行性をサポートする」を確認することを忘れないでください。

11
rmartinsjr

この方法を試してください:

if (manageObject.deleted) {
    // assume that the managed object has been deleted.
}
1
dusty

Swift 3、Xcode 7.3で検証済み

また、単に各コンテキストのメモリ参照をPRINTして確認することもできます

(a) if the context exists,
(b) if the contexts of 2 objects are different

例:(ブックとメンバーは2つの異なるオブジェクトです)

 print(book.managedObjectContext)
 print(member.managedObjectContext)

コンテキストは存在するが異なる場合は、このようなものを印刷します

0x7fe758c307d0
0x7fe758c15d70
0
Naishta