2012-11-19 7 views
6

私はこれら2つの呼び出しの間の文書化された違いを理解します。しかし、私が気づいた以下の観察された振る舞いの理由を知っている人は誰ですか:説明できないobjectWithIDとの違い:existingObjectWithID:

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

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

ドキュメントだけでは、この動作を説明するには不十分なようです。私はもちろん、それを経験するためにチョークすることができますし、 "私は今常に使用することを知っていますexistingObjectWithID:オブジェクトIDを渡すときに私の子供の編集コンテキストブロックを実行"しかし、私は不安を感じて、ここで何が起こっているのか正確に理解したい少なくとも私は、他のものと同じように1つを使用することによるパフォーマンス上の影響があるかどうかを理解することができますが、制約が何であるかを理解するために、私はコード内に不必要に実装しているそれを修正するために間違っているか非効率的な呼び出し)。

答えて

1

私は自分のコードでこの動作を見てきました(スタックトレースは火星からのものでしたが、問題の原因を追跡するのに時間がかかりました)、私の解決策は同じでした(objectWithID: existingObjectWithIDを使用するためのコンテキスト:)。

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

これで、新しく作成されたオブジェクトに関するXMLデータを取得し、そのデータを解析してコアデータにインポートするネットワークコールを実行しました。これは背景のスレッドで発生し、スレッドに限定された子インポートコンテキストを使用したスレッドにオブジェクトIDを渡します。

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

iOS6では、これは奇妙なスタックトレースで失敗し始めましたが、唯一の解決策はexistingObjectWithID:に移動することでした。テストの下では、この変更が適切に行われていることが確かな解決策です。

あなたのように、私はこれがなぜ機能するかについての決定的な声明を見つけようとしましたが、失敗しました。しかし、私のコードが示したパターンと、私が見ていたスタックのトレースが、何が起こっているのかを説明していると思います。私は常に永続的なストアからデータを取得しようとしているクラッシュを見ていました。私は、iOS5の下で、私がUIManagedDocumentを介して要求したセーブは、私の子スレッドが実行される前に発生していたと考えているので、objectWithID:を呼び出す前に新しいオブジェクトが永続化されました。私のクラッシュログからは、それはiOS6の場合には当てはまりません。オブジェクトが永続ストアに作成される前にスレッドが実行されるため、まだ子コンテキストにフェッチできません。私の前提は、existingObjectWithID:フェッチを試みる前に保留中のSQL I/Oが実行されていることを保証しているため、フェッチがワーカースレッドで発生したときに永続ストアが一貫しているということです。私はこれをサポートするための決定的なものを見つけることができませんでしたが、広範なテストがそれが起こっていることを裏付けるようです。

+1

ありがとうございました。私は今それを無視しているだけで、誰かがそれを(正常に)無視していることを知ることは有益です。私は今コーディングで非常に快適な場所にいて、このような "不明"または "未解決"の問題を抱えていると、私が始めていていつも心配しているような気がしますまたは私を噛むつもりですが、さらに道のりを下ります! – TheBasicMind

+0

説明と解決に感謝します。私はUIManagedDocumentを使用してこの問題にも対処しました。 existingObjectWithID:error:に切り替えた後の私の最初のテストは有望でした。 –

0

"既存のオブジェクト"をexistingObjectWithIDで取得してから、 "クラッシュオブジェクト"をobjectWithIDにすると、両方のオブジェクトが同じになります。

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

1

OPと同じ問題を持って、私は例外は、Appleのドキュメントに

If the object is not registered in the context, it may be fetched or returned as a fault. This method always returns an object. The data in the persistent store represented by objectID is assumed to exist—if it does not, the returned object throws an exception when you access any property (that is, when the fault is fired). The benefit of this behavior is that it allows you to create and use faults, then create the underlying data later or in a separate context.

あたりのようなデザインであると思いながら - つまり、データがまだ永続ストアではありません、それはです親コンテクストに座っている - それは私が単に親コンテクストで私の実現オブジェクトを取得することができないことは奇妙に思えます。私のオブジェクトにデータを入れるために永続ストアがそれについて知っていなければならないのはなぜですか?