2

私は長い間この問題の解決策を探していましたが、まだ解決していません。

コアデータを使用して iOS アプリを開発しています。同じ永続ストア コーディネーターを指す 2 つの管理対象オブジェクト コンテキスト (MOC) を作成しました。1 つの MOC (self.moc と呼ばれる) はメイン キューの同時実行で開始され、もう 1 つの mov (self.bmoc と呼ばれる) はプライベート キューの同時実行で開始されます。self.moc がメイン スレッドでのみ実行され、self.bmoc がそのperformBlockまたはperformBlockAndWaitブロック内でのみ実行されることを確認しました。

ただし、アプリが[self.bmoc save:nil]回線上でフリーズするという奇妙な状況に遭遇しました。保存アクションはperformBlockブロック内で実行されるため、デッドロックに達する理由がわかりません。[self.bmoc save:&error]その行でフリーズするので、ではなく使ってもエラーは出ませんnil

以下は、問題を再現するコードです。以下に似た機能がたくさんありますが、これだけが問題を引き起こします。問題の原因を突き止めることができず、洞察をいただければ幸いです。ありがとうございました!

-(void)createEmptyUserData {
    [self.bmoc performBlock:^{
        User* user = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:self.bmoc];
        /* sets user object */
        [self.bmoc save:nil];
    }];
}

注: このコードはメイン スレッドで実行されます。

4

1 に答える 1

0

そのような状況で「ハング」するのには、2 つの基本的な理由があります。

  1. performBlockAndWait またはその他の同期スレッド/キュー呼び出しへのネストされた呼び出しがあります。

  2. ブロックの 1 つが返されず、永久に実行されています。

これらはどちらも、「ハング」時に実行中の各スレッドのスタックを調べることで簡単に確認できます。

performBlock は単に実行ブロックを取得してキューに追加し、すぐに戻ります。次に、他のスレッドが実行ブロックをキューからポップして実行しています。

performBlockAndWait は、呼び出しスレッドのコンテキストで実行されます。基本的に、現在キューに入れられている実行ブロックが実行されるのを待ってから、要求されたコードを現在のスレッドで実行します。

通話が完了するまで返されません。

したがって、performBlockAndWait への複数のネストされた呼び出しがあるか、非同期実行ブロックの 1 つが完了していないかのどちらかでしょう。

ハング時のスタックを見てください...

または、ブロックの実行をログに記録して、各ブロックの開始時刻と終了時刻を確認できます。

于 2012-07-13T18:11:29.267 に答える