GCDはSwiftでスレッドプログラミングする時には避けて通れない道です。
これを使いこなせれば大抵のスレッド処理は賄えると思います。
以下の3パターンがあります。
* メインキュー (メインスレッドで行われる)
* グローバルキュー (別のスレッドでよろしく処理される)
* プライベートキュー (自分で作成したキューで処理する)
### メインキュー
メインスレッドで処理される。
UIの更新とかはこのスレッドで行わないとエラーになる。
```swift
`gutter:true;
// キューの取得
let mainQueue = DispatchQueue.main
// EXC_BAD_INSTRUCTION になる
// おそらく、MainスレッドからsyncでCallしたため、デッドロック
// mainQueue.sync {
// print("Hello! sync MainQueue")
// }
// 非同期で実行(おそらくこの処理が終わってからCallされる
mainQueue.async {
print("Hello! async MainQueue")
}
```
### グローバルキュー
```swift
`gutter:true;
// キューの取得
let globalQueue = DispatchQueue.global(qos: .default)
var greet = ""
// 同期的に処理
globalQueue.sync {
greet = "Hello!"
print("\(greet) Grobal Sync Queue")
}
// syncは同期的に処理されるので、スレッド処理の下で値にアクセスする事ができる
print("\(greet) grobalQueueSample")
// 非同期に処理
globalQueue.async {
print("\(greet) Grobal Async Queue")
}
```
### プライベートキュー
自分で作成するキューは並列処理するキューと逐次処理するキューを作成できる。
(作成時のパラメーターで振る舞いが変わる)
```swift
`gutter:true;
// 非同期的なプライベートキューを作成
// 非同期なので、タスクは並列に処理される
let concurrentPrivateQueue_: DispatchQueue = DispatchQueue(label: "ConcurrentQueue", qos: .userInteractive, attributes:.concurrent)
// 逐次処理するくキュー
// 処理が終わってから次の処理を行う
let oneByOnePrivateQueue_: DispatchQueue = DispatchQueue(label: "OneByOne", qos: .userInteractive, attributes:.initiallyInactive)
// テスト用の実行関数
func useQueue(label: String, queue: DispatchQueue) {
queue.async {
for i in 1...10 {
print("\(label) First \(i)")
}
}
queue.async {
for i in 1...10 {
print("\(label) Second \(i)")
}
}
queue.async {
for i in 1...10 {
print("\(label) Third \(i)")
}
}
}
// キューを使うサンプル
func privateQueueSample() {
// 逐次処理は開始しないと処理が実行されない
oneByOnePrivateQueue_.activate()
useQueue(label: "OneByOne", queue: oneByOnePrivateQueue_)
useQueue(label: "Concurrent", queue: concurrentPrivateQueue_)
}
privateQueueSample()
```
## 参考URL
* [Swift GCD入門](https://qiita.com/ShoichiKuraoka/items/bb2a280688d29de3ff18)
* [GitHub](https://github.com/k28/swift_study.git)
0 件のコメント :
コメントを投稿