1

私は現在、別の開発者が開発した (非常に) 大きなアプリケーションを使用しています。

それはよく開発されており、コードはかなりよく見えます...コアデータへのアクセスの代わりに。

実際、への各アクセスManagedObjectContextsは、いくつかの Web サービスに対応するいくつかのブロックで行われます... 複数のスレッドで。

ドキュメントには、それは悪いと書かれています。そのため、Core Data アクセスでアプリがフリーズすることがあります。

はい、そうすべきだとわかっています

スレッドごとに個別の管理対象オブジェクト コンテキストを作成し、単一の永続ストア コーディネーターを共有する

ドキュメントが言うように、しかしコードはすでに存在し、それは非常に巨大であり、私のクライアントは(いつものように)すぐに解決策を必要としています.

だからここに質問があります:

方法を見てきました[managedObjectContext lock]。セマフォのようです。しかし、ドキュメントはあまり話していません。

異なるスレッドの私の Web サービスは、managedObjectContext の同じインスタンスを使用しています。

――やってみたらどう思いますか

[managedObjectContext lock]
// core data access
// core data access
// core data access
[managedObjectContext unlock]

私のWebサービスブロックのそれぞれで?
-これでフリーズは解決しますか?
――おすすめの方法は?

lock&unlockメソッドについて誰も教えてくれなかったので、EDIT を作成しました。

デフリーズは毎回発生するわけではないので、3つのケースを試しました:

  • データ アクセスを保護しない

  • [managedObjectContext lock] unlock]メソッドを使用する

  • 使用する@synchronized(managedObjectContext) { ... }

最初のケースでは、10 回のテストで 3 回フリーズが発生しました。2 番目と 3 番目のケースでは、まったくフリーズしません。

だから私の2番目の質問:

lock/unlockとの違いは何@synchronize( )ですか?

4

2 に答える 2

4

私は同様の問題を抱えていました.既存のコードでは直接動作しませんでした.ブロックは単一の管理オブジェクトコンテキストでフェッチを実行し、奇妙なエラー、フリーズ、スレッドの終了などに終わりました.

コンテキストに同期を追加して解決しました:

NSBlockOperation *myBlock = [NSBlockOperation blockOperationWithBlock:^{

  // block operation

  @synchronized(managedObjectContext) {

    NSArray *result = [managedObjectContext performFetch:myFetch];

   // error management following

  }
}];

これは私が見つけた最も速い解決策です。また、ある種のロック条件を追加しようとしましたが、スレッドがめちゃくちゃになり、場合によってはデッドロックが発生しました。

于 2012-10-04T15:59:45.550 に答える
1

どの SDK で実行する必要があるかはわかりませんが、iOS 5 以降を使用できる場合は、-performBlock:必要-performBlockAndWait:なものだけかもしれません。

それが役立つことを願っています。

于 2012-10-04T16:22:30.100 に答える