Operationの実装方法には2種類あり、どちらのタイプも並列で処理されます。
| タイプ | 概要 |
|---|---|
| non-concurrent タイプ | 同期的なタスクをOperation化する |
| concurrent タイプ | 非同期的なタスクをOperation化する |
non-concurrentタイプ
画像の合成など同期的な処理をOperation化したい場合は、non-concurrent タイプを実装します。
以下のメソッドをオーバーライドします。
main()
実装例
class RequestOperation: Operation {
func main() {
//同期的なタスクを実装すること
self.createImage()
//main関数終了後自動的にqueueから削除される
}
}
mainメソッド終了後、OperationQueueから削除される
したがって非同期的な処理が実装できないため、非同期的なタスクは concurrentタイプを実装します。
concurrentタイプ
ネットワークからのデータの取得やストレージへの保存など非同期的な処理をOperation化したい場合は、concurrentタイプを実装します。
以下のメソッドをオーバーライドします。
-
start()このメソッドから処理が抜けてもQueueから削除されません。 isFinished { get }isExecuting { get }-
isAsynchronous { get }※もはや無視されている
以下の状態変更はKVOで通知します。
-
isFinished { set }この値がtrueになった時にOperationQueueから削除される isExecuting { set }-
isAsynchronous { set }※もはや無視されている
処理がstartメソッドを抜けてもOperationQueueから削除されません。
OperationQueueからの削除はisFinishedプロパティがtrueになったときです。
(KVOで通知する必要があります。)
class RequestOperation: Operation {
var object: Object? = nil
enum State {
case ready
case executing
case finished
}
private var state = State.ready {
didSet {
switch self.state {
case .ready: break
case .executing:
self.isExecuting = true
case .finished:
self.isExecuting = false
self.isFinished = true
}
}
}
private var _executing: Bool = false
override var isExecuting: Bool {
get {
return _executing
}
set {
if _executing != newValue {
self.willChangeValue(for: \RequestOperation.isExecuting)
_executing = newValue
self.didChangeValue(for: \RequestOperation.isExecuting)
}
}
}
private var _finished: Bool = false;
override var isFinished: Bool {
get {
return _finished
}
set {
if _finished != newValue {
self.willChangeValue(for: \RequestOperation.isFinished)
_finished = newValue
self.didChangeValue(for: \RequestOperation.isFinished)
}
}
}
init(object: Object?) {
super.init()
self.object = object
}
override func start() {
guard self.isCancelled == false else {
// Queueから削除される
self.state = .finshed
return
}
self.state = .executing
// データストアへの登録を実施
object?.saveInBackground({ (error) in
if error != nil {
// 保存に失敗した場合の処理
} else {
// 保存に成功した場合の処理
}
// Queueから削除される
self.state = .finished
})
// startメソッドが終了してもQueueから削除されない
}
}
参照
[Qiita] Operation(NSOperation)について
今読むと分かりにくかったのでまとめ直しました。