16
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

main thread で動作させる話

16
Last updated at Posted at 2016-02-04

Main Thread で動作させたいコードなどが時々あります。 UITableViewreloadData() などは、場合によって、autolayout を background thread でやるなみたいなメッセージをもらったり、Core Data や OpenGL のように やっぱりちゃんと main thread で呼び出したい場合などが考えられます。

もっともオーソドックスなやり方は、以下のような書き方かもしれません。

.swift
dispatch_async(dispatch_get_main_queue()) { () -> Void in
	self.tableView.reloadData()
}

さてしかし、処理の順番などなんらかの都合で、dispatch_sync() を使いたい時は、こんなコードを書きたいと一瞬思うかもしれませんが、これを、main thread から呼び出してはいけません。

.swift
doStep1()  // 時間のかかる処理等
dispatch_sync(dispatch_get_main_queue()) { () -> Void in
	doStep2()  // step1 の結果を保存・表示する場合に main thread が必要な場合
}
doStep3()  // 後始末等

ならば、NSThread.isMainThread() で main thread かどうか、判定すればいいと思うかもしれませんが、同じコードを二回書かなくてはなりません。

.swift
if NSThread.isMainThread() {
	// your code
}
else {
	dispatch_sync(dispatch_get_main_queue()) { () -> Void in
		// your code
	}
}

で、技巧的に走って

.swift
let yourCode: () -> Void = {
	// your code
}

if NSThread.isMainThread() {
	yourCode()
}
else {
	dispatch_sync(dispatch_get_main_queue()) { () -> Void in
		yourCode()
	}
}

と書くこともできますが、似たような処理の都度何度もこんな書き方をするのは面倒で、なおかつ可読性が落ちます。そこで、より使いかってを考えれば、そもそも引数としてコードを渡せるので、同期用と非同期用の二種類の関数を用意すれば便利になりそうです。

dispatch_sync_main.swift
func dispatch_sync_main(block: () -> Void) {
	if NSThread.isMainThread() {
		block()
	}
	else {
		dispatch_sync(dispatch_get_main_queue()) { () -> Void in
			block()
		}
	}
}
dispatch_async_main.swift
func dispatch_async_main(block: () -> Void) {
	dispatch_async(dispatch_get_main_queue()) { () -> Void in
		block()
	}
}

こんな感じで、使いかってがよくなると思います。

.swift
	doStep1()
	dispatch_sync_main() {
		doStep2()
	}
	doStep3()
	dispatch_async_main() {
		self.tableView.reloadData()
	}

ネーミングが本物のGCDとまぎわらしいと思う場合は、_ をつけるなり、他の名前をつけるなり工夫しましょう。

16
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?