web-dev-qa-db-ja.com

メインスレッドでメソッドを呼び出しますか?

まず、私はiPhone用のコードを書いています。 performSelectorOnMainThreadを使用せずにメインスレッドでメソッドを呼び出すことができる必要があります。 performSelectorOnMainThreadを使用したくないのは、単体テスト用のモックを作成しようとすると問題が発生するためです。

[self performSelectorOnMainThread:@Selector(doSomething) withObject:nil];

問題は、私のモックはdoSomethingを呼び出す方法を知っているが、performSelectorOnMainThreadを呼び出す方法を知らないことです。

解決策はありますか?

73
aryaxt

Objective-C

dispatch_async(dispatch_get_main_queue(), ^{
  [self doSomething];
});

スイフト

dispatch_async(dispatch_get_main_queue()) {
   self.doSomething()
}

Swift 3および4

DispatchQueue.main.async {
   self.doSomething()
}
236
aryaxt

ソフトウェアには、インダイレクションのレイヤーを追加するとほとんど何でも修正されるという格言があります。

DoSomethingメソッドを、実際にSomethingを実行するためにreally_doSomethingメソッドを呼び出すperformSelectorOnMainThreadのみを実行する間接シェルにします。または、doSomethingメソッドを変更したくない場合は、模擬テストユニットでdoSomething_redirect_Shellメソッドを呼び出して同様のことを行います。

2
hotpaw2

そして今Swift 3:

DispatchQueue.main.async{
   self.doSomething()
}
1
RomOne

Swiftでこれを行うより良い方法は次のとおりです。

runThisInMainThread { () -> Void in
    // Run your code
    self.doSomething()
}

func runThisInMainThread(block: dispatch_block_t) {
    dispatch_async(dispatch_get_main_queue(), block)
}

それは私のレポの標準機能として含まれています、それをチェックしてください: https://github.com/goktugyil/EZSwiftExtensions

1
Esqarrouth