0

データを plist ファイルに保存する単純なアプリケーションがあり、このデータを操作する必要があります。そのため、データを保存するプロセスには約 5 秒かかり (提案を研究するための人為的な遅延)、同時に plist のデータを読み取る必要があります (たとえば、2 番目の画面に表示するため)。

まず最初に、save メソッドを移動しました

dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{});

と read メソッド

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{});

しかし、保存プロセス中に plist を読み込もうとしたときに問題が発生する可能性があると思います。

とにかく、画面をフリーズする必要はありません。複数のスレッドで plist の I/O プロセスを正しく行うには? 読み取り/書き込みに 2 つの異なるキューを使用する必要がありますか? それらを同期する方法は?

4

2 に答える 2

3

ヒント: リーダー/ライター アクセスでパフォーマンスを向上させる

• 同時サブシステム キューを使用する

  • DISPATCH_QUEUE_CONCURRENT

• 同期同時「読み取り」を使用する</p>

  • ディスパッチ_同期()

• 非同期のシリアル化された「書き込み」を使用する</p>

  • dispatch_barrier_async()

例:

// ...
   _someManagerQueue = dispatch_queue_create("SomeManager", DISPATCH_QUEUE_CONCURRENT);
// ...

init や nib の起動などでキューを作成できます。同じインスタンスで関数を複数回呼び出すことができる場合は、dispatch_once を使用します。

それで:

 - (id) getSomeArrayItem:(NSUInteger) index {
    id importantObj = NULL;
    dispatch_sync(_someManagerQueue,^{
        id importantObj = [_importantArray objectAtIndex:index];
     });
   return importantObj;
 }
- (void) removeSomeArrayItem:(id) object {
     dispatch_barrier_async(_someManagerQueue,^{
         [_importantArray removeObject:object];
     });
 }
- (void) addSomeArrayItem:(id) object {
     dispatch_barrier_async(_someManagerQueue,^{
         [_importantArray addObject:object];
     });
 }

そうすれば、情報(配列など)を読み取るたびに、すべての「変更」が行われたか、「待機」していることを確認できます。また、情報を書き込むたびに、操作が完了するのを待ってプログラムがブロックされることはありません。

シリアル キューを使用することもできますが、これは処理の膨大な無駄であり、時間は読み取りを並列化しません。そうすれば、複数のスレッドを使用する場合、「書き込み」でない限り、別のスレッドを待つ必要はありません。これは正しいことです。

詳細情報: WWDC 2012 セッション 712

于 2013-09-02T14:14:32.593 に答える