2013-02-06 20 views
7

本来、私はNSDictionaryのデータセットを持っていますが、便宜上、いくつかの方法でデータをソートしてフィルタリングしてNSArrayを設定しています。データは別のスレッド(ブロック)を介して入力されます。データストアを変更する際にブロックが1つしかないことを確認します。@synchronizedブロック対GCD dispatch_async()

私は今日の午後にディスパッチキューを設定する手間を経て、ランダムに、@synchronizedについての投稿に遭遇しました。

だから私は今でてきたものを...

// a property on my object 
@property (assign) dispatch_queue_t matchSortingQueue; 

// in my object init 
_sortingQueue = dispatch_queue_create("com.asdf.matchSortingQueue", NULL); 

// then later... 
- (void)sortArrayIntoLocalStore:(NSArray*)matches 
{ 
    dispatch_async(_sortingQueue, ^{ 
     // do stuff... 
    }); 
} 

そして、私の質問は、私は次のようにこのすべてを置き換えることができますか?

- (void)sortArrayIntoLocalStore:(NSArray*)matches 
{ 
    @synchronized (self) { 
     // do stuff... 
    }; 
} 

...とにかく2つの違いは何ですか?私は何を考慮すべきですか?

+0

'@ synchronized'は本当に遅いです。私が今見ている指標を見つけることができませんが、https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.htmlもチェックしてください。 – Richard

+0

あなたのデータが同じディスパッチキュー(同じスレッド)を介して入ってくる場合、それらは衝突しません。異なるキュー(異なるスレッド)を使用する場合は、同期が必要です。 – Jeremy

+0

それを見つけました(http://stackoverflow.com/q/10094361/480850経由):http://perpendiculo.us/?p=133 – Richard

答えて

5

機能上の違いはあなたにはあまり重要ではないかもしれませんが、それはあなたが期待するものです。@synchronizeあなたが行っているスレッドは、排他的実行ができるまでブロックされます。シリアルディスパッチキューに非同期でディスパッチすると、呼び出し元のスレッドは他のものとやりとりすることができ、実際に何をしているのかは常に同じ既知のキューで発生します。

これは、一度に1つのキューから3つ目のリソースを確実に使用することと同等です。

たとえば、メインキューからユーザーインターフェイスによってアクセスされたリソースがあり、それを変更したいと思った場合、ディスパッチはより良い考えです。その後、ユーザーインターフェイスコードは明示的に@synchronizeにする必要はなく、非常に自然にオブジェクト内のスレッドスキームの複雑さを隠します。他のさまざまなアクターでこれらの変更のいくつかを引き起こすことができる中心的な俳優があれば、ディスパッチングも良い考えです。同時に動作させることができます。

シンクロナイゼーションはよりコンパクトで、デバッグのステップがずっと簡単です。あなたがやっていることが2〜3行になる傾向があり、それを同期させて送信する必要があるなら、待ち行列を作成しようとするような気がしません。特に、作成の暗黙のコストブロックを移動してヒープに移動します。

+0

詳細な回答ありがとうございます。結局のところ、非同期待ち行列のように思える。 – livingtech

4

「do stuff」が実行されるまで、呼び出しスレッドをブロックします。キューとdispatch_asyncを使用すると、呼び出しスレッドをブロックしません。これは、UIスレッドからsortArrayIntoLocalStoreを呼び出す場合に特に重要になります。

関連する問題