iOSアプリケーションのバックグラウンドで多くのことをしたいが、スレッドを作成するように正しくコーディングするとしますこのバックグラウンド活動。同期されたキーワードがメインスレッドをブロックしない方法です
ここで、ある時点で変数の更新を書き込む必要がある場合、この更新が発生するか、または作成したスレッドのいずれかが発生する可能性があります。
あなたは明らかにその変数を保護したいとあなたはあなたのためにロックを作成するために、キーワード@synchronized
を使用することができますが、ここでキャッチ(アップルのドキュメントから抜粋)
ある
@synchronized()
ディレクティブは、コードのセクションをロック単一スレッドで の使用のために。スレッドが 保護されたコードを終了するまで、つまり実行が@synchronized()
ブロック内の最後の ステートメントを過ぎて継続するまで、他のスレッドはブロックされます。
だからそれはあなたがオブジェクトを同期して2つのスレッドが同時にそれを書いている場合は、両方のスレッドがそのデータの書き込み完了するまで、でも、メインスレッドがブロックされることを意味します。
このすべてを紹介するコードの例:
// Create the background queue
dispatch_queue_t queue = dispatch_queue_create("synchronized_example", NULL);
// Start working in new thread
dispatch_async(queue,^
{
// Synchronized that shared resource
@synchronized(sharedResource_)
{
// Write things on that resource
// If more that one thread access this piece of code:
// all threads (even main thread) will block until task is completed.
[self writeComplexDataOnLocalFile];
}
});
// won’t actually go away until queue is empty
dispatch_release(queue);
そこで問題は非常に簡単です:これを克服するためにどのように?どのようにして、すべてのスレッドにロックを安全に追加することができますか?その場合、ブロックする必要のないメインスレッドを除きますか?あなたはあなたのいくつかは、コメントとして、それは論理的なようです(これが同期を使用するときに私が最初に考えたもの明らかにした)ロックを取得しようとしている2つだけのスレッドその明確化
FOR
EDIT両方が完了するまでブロックする必要があります。
しかし、実際の状況でテストした場合、これは当てはまりそうもなく、メインスレッドもロックに苦しんでいるようです。
私はこのメカニズムを使用して、UIがブロックされないように物を別々のスレッドに記録します。しかし、私が強烈なロギングを行うと、UI(メインスレッド)は明らかに非常に影響を受けます(スクロールはスムーズではありません)。
バックグラウンドタスクが重すぎてメインスレッドでさえ影響を受ける(疑わしい)、または同期化によってロック操作を実行中にメインスレッドがブロックされる(再考を開始している) 。
私はもう少し時間プロファイラを使用して掘り下げます。
メインスレッドがロックを取得する必要があるのはなぜですか?それはどのように他のどのスレッドとも違うのですか? –
データを書き込むコードが非同期的にキューにディスパッチされるため(dispatch_async) – apouche
これが表示されます。しかし、メインスレッドが同期化されたコードを決して呼び出さない場合、ブロックされません(他のものが言及したように)。あなたはそれをテストしましたか? –