これまでの各記事は、以下から。
- Swiftでの並列プログラミングについて調べてみた。(その1) - いものやま。
- Swiftでの並列プログラミングについて調べてみた。(その2) - いものやま。
- Swiftでの並列プログラミングについて調べてみた。(その3) - いものやま。
- Swiftでの並列プログラミングについて調べてみた。(その4) - いものやま。
- Swiftでの並列プログラミングについて調べてみた。(その5) - いものやま。
オペレーションキューとオペレーションオブジェクト
並列処理を行うには、オペレーションキューを用意して、そこに処理をオブジェクト化したオペレーションオブジェクトを追加する。
オブジェクトの生成と実行
// Foundationのインポートが必要。 import Foundation // オペレーションキューを生成。 let queue = NSOperationQueue() // オペレーションオブジェクトを生成。 // Swiftの場合、クロージャを使うといい。 let operation = NSBlockOperation { // 並列で行いたい処理 } // オペレーションキューにオペレーションオブジェクトを追加すると、 // 処理が並列で行われる。 queue.addOperation(operation)
排他制御
オペレーションキューが同時に実行できる処理の最大数を指定することが出来る。
これを1にすれば、そのオペレーションキューに追加された処理は、同時には最大1つしか実行されないので、排他制御が出来る。
// 同時に実行できる処理の最大数を1にする。 queue.maxConcurrentOperationCount = 1
処理の同期
キューが空になるのを待ったり、処理が終了するのを待ったりすることも出来る。
// キューが空になるのを待つ queue.waitUntilAllOperationsAreFinished() // 処理が終了するのを待つ operation.waitUntilFinished()
メインキューと実行ループ
メインスレッドに関連付けられたメインキューを使うことも出来る。
ただし、その場合、メインスレッドで実行ループが回っていないといけない。
メインキューに追加された処理は、同時に最大1つまでしか実行されないので、排他制御にも使える。
// メインキューを取得 let mainQueue = NSOperationQueue.mainQueue() // メインスレッドで実行ループを回す NSRunLoop.mainRunLoop().run()
依存関係の設定
処理間に依存関係を設定すると、依存する処理が終わってからでないと処理が開始されなくなる。
let opA = NSBlockOperation { /* 処理A */ } let opB = NSBlockOperation { /* 処理B */ } // 処理Bを行うより前に、処理Aを行う必要があるとする。 // (つまり、処理Bは処理Aに依存している) // その場合、依存関係を追加する。 opB.addDependency(opA)
処理のキャンセル
処理のキャンセルを行うことも出来る。
ただし、キャンセルされる処理がキャンセルに対応している必要がある。
let operation = NSBlockOperation {} operation.addExecutionBlock { [unowned operation] in // 何か処理 // キャンセルされたかどうかをチェックする。 // キャンセルされていれば、処理を終了する。 if operation.cancelled { return } // 何か処理 } queue.addOperation(operation) // 処理をキャンセルする。 operation.cancel()
ディスパッチキュー
ディスパッチキューにブロックを追加すると、追加された順にブロックが実行されていく。
昨日の記事がほぼまとめなので、以下を参照。
今日はここまで!