2

私は iOS 6.1 のコーディングを行っており、Core Data の使用方法を学んでいます。

fetchedObjects のドキュメントには次のように書かれています。

「結果配列は、永続ストア内の状態ではなく、コントローラーの管理対象オブジェクト コンテキスト内の管理対象オブジェクトのメモリ内状態を反映します。ただし、返される配列は、管理対象オブジェクトが挿入、変更、または削除されても更新されません。」

その最後の文は、私が見ているものに関係しています。

つまり、エンティティからデータをフェッチし、フェッチされたオブジェクト (fetchedObjects.count) のカウントを実行すると、期待どおりの結果が得られます。

次に、新しいオブジェクトを作成して保存し、もう一度 fetchedObjects.count を実行すると、前回と同じ結果が得られました。

したがって、私の問題は、コンテキストを保存した後に fetchedObjects を更新する方法でした。

ここでNSFe​​tchedResultsControllerDelegateの使用について読み、デリゲートを使用するという提案されたもののいくつかを試しました。

私は代理として自分自身を割り当てました。

 frc.delegate = self;

次のようにデリゲートを追加しました。

@interface DB : NSObject <NSFetchedResultsControllerDelegate>

そして、次のようにデリゲート コールバックを実装しました。

- (void) controllerDidChangeContent: (NSFetchedResultsController *) controller
    {
    ;
    }

そして、それはすべてうまくいきました。しかし、私はその理由を理解していません。

上記のデリゲート コードの 3 ビットを削除すると、新しいオブジェクトを作成し、コンテキストを保存してから fetchedObjects.count を実行すると、コードが失敗します。カウントが 1 つ不足して失敗します。

NSFetchedResultsControllerDelegate と frc.delegate = self; を追加すると、ビットとコールバック ルーチンを省略しても、それでも失敗します。

コールバック ルーチンを再度追加した場合にのみ (ちなみに、これは機能しません)、私のコードは成功します。

これは私を少し偏執狂にさせます-コールバックが何もしないのになぜそれが機能するのか、そしてこれが99%の確率で機能し、その後ブルームーンで一度失敗するのか疑問に思うのと同じように?

そのため、ブール値を作成し、それをコールバック ルーチンに設定して、ブール値の反転が見られるまでコードが保存後のカウントを実行しないようにしました。しかし、これは冗長で、ばかげているかもしれないと考えています。

oldCount = frc.fetchedObjects.count;
<create a new object here>
frcDelegateCalled = FALSE;   
[self saveDB];   
[frc.managedObjectContext processPendingChanges];   
while ( frcDelegateCalled == FALSE );   
newCount = frc.fetchedObjects.count;

- (void) controllerDidChangeContent: (NSFetchedResultsController *) controller
   {
   frcDelegateCalled = TRUE;
   }

そのため、processPendingChanges 呼び出しは明らかに更新を急いでおり、boolean はコールバックが呼び出されたことを確認し、詳しく説明する前に fetchedObjects が更新されたことを示します。

コールバックが存在するという理由だけでコードが機能する理由について、私は少し混乱しています。誰かがここで光を当てることができますか?

4

1 に答える 1

3

内部にアクセスできる人だけが確実に答えることができますが、これが私の推測です。

NSFetchedResultsController はNSManagedObjectContextObjectsDidChangeNotification、大量に送信される をリッスンすることで機能します。最適化として、デリゲートを取得していない場合、またはデリゲートが一部またはすべてのメソッドを実装していない場合、フェッチされた結果コントローラーはおそらく通知に応答して何もしません。

MartinR が言及しているように、これは実際にはドキュメントに記載されており、あなたが見ているのは予想される動作です:

重要:デリゲートは、変更追跡を有効にするために、少なくとも 1 つの変更追跡デリゲート メソッドを実装する必要があります。controllerDidChangeContent: の空の実装を提供するだけで十分です。

フェッチの結果がいつ変化するかを知りたい場合は、とにかく FRC デリゲート メソッドを使用する必要があります。

于 2013-09-08T18:31:01.687 に答える