RxSwiftでdeinitまで処理をdeferする

Swiftでdeinitまで処理をdeferする – TOKOROM BLOGという記事を見かけたので、RxSwiftで同様の事を行うコードを書いてみる。

まずdeinitで処理を行いたいクラス等にDisposeBagを持たせる。

class SampleViewController: UIViewController {
let disposeBag = DisposeBag()

ロガーを登録するところは同様に行う。

let logger = DDASLLogger.sharedInstance()
DDLog.addLogger(logger)

RxSwiftのAnonymousDisposableを作成して、disposeするときに実行するアクションを記述する。そしてそのAnonymousDisposableをdisposeBagに登録する。

let disposable = AnonymousDisposable {
DDLog.removeLogger(logger)
}
disposeBag.addDisposable(disposable)

こうする事で、SampleViewControllerのdeinitでdisposeBagがリリースされる時にAnonymousDisposableがdisposeされ、登録したアクションが実行されることにより、loggerがremoveされることになる。

すべてのコードは以下のようになる。

class SampleViewController: UIViewController {

let disposeBag = DisposeBag()

override func viewDidLoad() {
super.viewDidLoad()

let logger = DDASLLogger.sharedInstance()
DDLog.addLogger(logger)
let disposable = AnonymousDisposable {
DDLog.removeLogger(logger)
}
disposeBag.addDisposable(disposable)
}
}

で、これを簡単に書く為の関数を作成してみた。

        func actionAndDefer<T>(action: () -> T, deferAction: T -> ()) -> Disposable {
            return create { observer in
                let obj = action()

                observer.onNext("")

                let disposable = AnonymousDisposable {
                    deferAction(obj)
                }

                return disposable
                }.subscribeNext { (value: String) -> Void in }
        }

        actionAndDefer({ () -> DDLogger in
            let logger = DDASLLogger.sharedInstance()
            DDLog.addLogger(logger)
            return logger
            }, deferAction: { logger -> () in
                DDLog.removeLogger(logger)
        }).addDisposableTo(disposeBag)

RxSwiftの事をまだ把握しきれていないのでもっと良い書き方があると思うけど、とりあえずこれでactionAnDeferを実行してdisposeBagに登録すると利用できる。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です