2017-04-07 12 views
0

同じスレッドからコードブロックに繰り返しアクセスするのを防ぐにはどうすればよいですか?私は「//いくつかの同期作業」完了が呼び出される前に、アクセスするに任意のスレッドを防ぎたいシングルスレッドでの複数のタスクの同期

func sendAnalytics() { 
    // some synchronous work 

    asyncTask() { _ in 
     completion() 
    } 
} 

と仮定、私は次のコードを持っています。

objc_sync_enter(self) 
objc_sync_exit(self) 

複数のスレッドからこのコードにアクセスすることを防ぐだけで、このコードを単一スレッドからアクセスできないように見えます。カスタムソリューションを使用せずにこれを正しく行う方法はありますか?

繰り返しアクセスしていますが、私はこのsendAnalyticsをあるスレッドから複数回呼び出すことを意味します。

for i in 0...10 { 
    sendAnalytics() 
} 

すべての次の呼び出しがsendAnalytics内で完了するのを待っていることはありません(明確な)と呼ばれます:私はこのような、のために持っている、と仮定します。完成が始まる前に次のコールを待つ方法がありますか?あるいは、考え方全体が間違っていて、私はこの問題をより身体的に解決しなければなりませんか?

+0

最初が終了または単に2回目の呼び出しに – Paulw11

+0

ブロックスキップするまで、それはあなたが第二の呼び出し元をブロックするかどうかによって決まります2番目の呼び出し側 –

+0

次に、初期カウント0のdispatch_semaphoreを使用します。しかし、メインキューをブロックすることに注意してください。 – Paulw11

答えて

2

あなたは次は最初asyncTaskが完了するまでsendAnalyticsへの2回目の呼び出しはブロックされます

let semaphore = DispatchSemaphore(value:1) 

func sendAnalytics() { 
    self.semaphore.wait() 
    // some synchronous work 

    asyncTask() { _ in 
     completion() 
     self.semaphore.signal() 
    } 
} 

を開始する前に1つの呼び出しが完了することを保証するためにDispatchSemaphoreを使用することができます。メインキューをブロックしないように注意してください。そうすれば、アプリが応答しなくなるからです。このリスクを排除するために、独自のシリアルディスパッチキューにsendAnalytics呼び出しをディスパッチする、おそらく安全です:

let semaphore = DispatchSemaphore(value:1) 
let analyticsQueue = DispatchQueue(label:"analyticsQueue") 

func sendAnalytics() { 
    analyticsQueue.async { 
     self.semaphore.wait() 
     // some synchronous work 

     asyncTask() { _ in 
      completion() 
      self.semaphore.signal() 
     } 
    } 
} 
+0

それはまったく呼び出しません。しかしそれはのために働きます セマフォ=ディスパッチセマフォーレ(値:1) –

+0

申し訳ありません、私の間違い。 1が正しい – Paulw11

関連する問題