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)について
今読むと分かりにくかったのでまとめ直しました。