8

これら 2 つの呼び出しの文書化された違いを理解しています。ただし、私が気付いた次の観察された動作の理由を知っている人はいますか?

parentContext と一時的な childContext がある場合、ここで childContext を使用してオブジェクトを編集、挿入、および削除します。親コンテキストに存在する既知の既存の管理対象オブジェクトを取得するために、起動時に失敗して例外を生成する障害のあるオブジェクトが表示されることがあります。objectWithID: は、設計上、指定された objectID に対して実際の managedObject が存在するかどうかに関係なく、常に障害状態のオブジェクトを返すことを理解しています。ただし、オブジェクトが実際に親コンテキストに存在する場合、プロパティのいずれかにアクセスすると、オブジェクトは常に問題なく親コンテキストから正常に取得される (たとえば、障害が発生する) と予想されます。[childContext existingObjectWithID:objectID]; を使用すると、私はそれが確かに常に成功することを発見しました。

記録のために、私は子コンテキストのキャッシュをオフにしましたが、これと同じ動作は [childContext resetContext] が呼び出された後に発生します。つまり、親コンテキストと矛盾する古いキャッシュ データのアーティファクトではありません。

ドキュメントだけでは、この動作を説明するには不十分なようです。もちろん、経験に基づいて「常に既存のObjectWithIDを使用することを知っています。オブジェクトIDを子編集コンテキスト実行ブロックに渡すとき」と言うことができますが、不安を感じ、ここで何が起こっているのかを正確に理解したいと思います(少なくとも、一方を他方よりも使用することでパフォーマンスに影響があるかどうかを理解できるだけでなく、制約が何であるかを理解して、コードに不必要に実装してからそれを修正するための間違ったまたは非効率的な呼び出し)。

4

3 に答える 3

2

私は自分のコードでこの動作を見てきました (スタック トレースは火星からのもので、問題の原因を突き止めるのに永遠にかかりました)、私の解決策は同じでした (子コンテキストでの objectWithID: の使用から の使用への移行)。 existingObjectWithID:)。

私の場合、親コンテキストでオブジェクトを作成し、すぐに永続的なオブジェクト ID を取得し、UIManagedDocument の updateChangeCount:UIDocumentChangeDone を使用して保存を要求します。これにより、将来のある時点で保存がスケジュールされます。この点が議論の鍵だと思います。

次に、ネットワーク呼び出しを実行して、新しく作成されたオブジェクトに関連する XML データを取得し、そのデータを解析して Core Data にインポートします。これはバックグラウンド スレッドで発生し、スレッドに限定された子インポート コンテキストを使用するスレッドにオブジェクト ID を渡します。

iOS5 では、ワーカー スレッドで objectWithID: を使用して、新しいオブジェクトをインポート コンテキストにフォールトさせます。問題なく動作しました。

iOS6 では、これは奇妙なスタック トレースで失敗し始め、唯一の解決策は existingObjectWithID: に移動することでした。テスト中、この変更により、確実なソリューションのように見えます。

あなたと同じように、私はこれが機能する理由について決定的な声明を見つけようとしましたが、うまくいきませんでした. しかし、私のコードが示したパターンと私が見たスタック トレースは、おそらく何が起こっているのかを説明していると思います。永続ストアからデータを取得しようとすると、常にクラッシュが発生していました。iOS5 では、子スレッドが実行される前に UIManagedDocument を介して要求した保存が発生していたため、objectWithID: を呼び出す前に新しいオブジェクトが保持されていたと思います。私のクラッシュ ログを見ると、iOS6 ではそうではないことがわかります。オブジェクトが永続ストアに到達する前にスレッドが実行されるため、まだ子コンテキストにフェッチできません。私の仮定では、existingObjectWithID: は、保留中の SQL I/O がフェッチを試行する前に確実に実行されるようにすることです。したがって、ワーカースレッドでフェッチが発生したときに、永続ストアは一貫しています。これを裏付ける決定的なものを見つけることはできませんでしたが、広範なテストにより、それが起こっていることが裏付けられているようです.

于 2012-11-25T15:40:27.657 に答える
0

existingObjectWithID「クラッシュオブジェクト」を使用して取得する前に「既存のオブジェクト」を取得するobjectWithIDと、両方のオブジェクトが等しくなります。

逆に、「クラッシュ オブジェクト」のプロパティにアクセスするとすぐにアプリがクラッシュします。この場合、オブジェクトは等しくありません。「クラッシュ オブジェクト」には一時的な ObjectID があります。

于 2013-03-14T08:56:02.393 に答える