4

我正在尝试将我对 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() {

}
4

5 回答 5

7

您可以使用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)
        }
    }
}

输出:

下一个([])
完成

于 2016-09-27T19:22:23.047 回答
4

您应该对函数使用dynamic修饰符,因为编译器永远不会对test函数的访问进行内联或去虚拟化。test

像这样: dynamic func test() {}

于 2017-07-27T03:29:52.890 回答
2

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

对我来说,解决方案——如果这不是你要搜索的东西,我很抱歉,但希望能帮助其他人解决同样的问题——只是dynamic为观察到的函数添加修饰符。

这是代码

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

@objc dynamic test() {}

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

我是 RxSwift 的新手。

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

于 2018-02-23T06:57:10.963 回答
0

另一种避免使用 sentMessage 的解决方案是定义一个 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() 之前打印。

于 2019-04-10T14:22:28.723 回答
0

RxSwift 已经添加了这个方法。看这个问题

于 2019-11-07T02:01:57.657 回答