选择器可观察 - RxSwift

时间:2016-09-26 17:01:10

标签: ios swift rx-swift reactivex rx-cocoa

我试图将我的FRP理解从 ReactiveCocoa 2.5 迁移到 RxSwift ,我有一个误解。在ReactiveCocoa中,当我想观察方法的调用时,我使用了rac_signalForSelector。有没有办法使用RxSwift实现这个逻辑?

我写了一个小例子,我希望在test方法调用时处理订阅。但是在订阅块中我仍然可以看到next(6)事件。我做错了什么?

let subject = PublishSubject<Int>()
subject.takeUntil(self.rx.sentMessage(#selector(test))).subscribe { event in
    print(event)
}

subject.onNext(3)
test()
subject.onNext(6)

//////////////////

func test() {

}

5 个答案:

答案 0 :(得分:6)

您可以使用sentMessage

class ViewController: UIViewController {

    let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.rx.sentMessage(#selector(UIViewController.viewWillAppear(_:)))
            .subscribe({ e in
                print(e)
            })
            .addDisposableTo(disposeBag)
    }
}

输出:

  

下([0])

或另一个例子:

class SomeNSObjectClass: NSObject {
}

class ViewController: UIViewController {

    let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()

        let myObj = SomeNSObjectClass()
        myObjc.rx.sentMessage(NSSelectorFromString("dealloc"))
            .subscribe({ e in
                print(e)
            })
            .addDisposableTo(disposeBag)
        }
    }
}

输出:

  

下([])
  完成

答案 1 :(得分:2)

您应该对dynamic函数使用test修饰符,以免编译器对test函数的访问进行内联或虚拟化。

像这样: dynamic func test() {}

答案 2 :(得分:2)

我在遇到同样的问题后添加了此评论,但现在我已经解决了。

我的解决方案, - 我很抱歉,如果这不是您搜索的内容,但希望可以帮助其他人解决相同问题 - 只是为观察到的函数添加dynamic修饰符。

这是代码

func viewDidLoad() {
    rx.sentMessage(#selector(ViewController.test))
        .debug("Test", trimOutput: true)
        .subcribe()
        .disposed(by: bag)
}

@objc dynamic test() {}

如果没有dynamic修饰符,则无法观察到对测试的调用,因为调试不会打印任何内容。

我是RxSwift的新手。

感谢上面的@zhongwuzw,我在阅读他的评论后得到了这个想法。

答案 3 :(得分:0)

另一种避免使用sendMessage的解决方案是定义一个testSubject并在测试函数中触发一个下一个事件。

let subject = PublishSubject<Int>()
let testSubject = PublishSubject<Void>()

subject.takeUntil(testSubject).subscribe { event in
    print(event)
}

subject.onNext(3)
test()
subject.onNext(6)

//////////////////

func test() {
    testSubject.onNext(())
}

这只会打印直到调用test()为止。

答案 4 :(得分:0)

RxSwift已添加此方法。 看看这个issue