可观察的选择器 - RxSwift
Observable for selector - RxSwift
我正在尝试将我对 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() {
}
您可以使用 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)
}
}
输出:
next([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)
}
}
}
输出:
next([])
completed
您应该对 test
函数使用 dynamic
修饰符,编译器永远不会内联或去虚拟化对 test
函数的访问。
像这样:
dynamic func test() {}
我遇到同样的问题后添加此评论,但现在我已经解决了。
我的解决方案 -- 如果这不是您要搜索的内容,我很抱歉,但希望能帮助其他人解决同样的问题 -- 只是为观察到的函数添加 dynamic
修饰符。
这是代码
func viewDidLoad() {
rx.sentMessage(#selector(ViewController.test))
.debug("Test", trimOutput: true)
.subcribe()
.disposed(by: bag)
}
@objc dynamic test() {}
如果没有 dynamic
修饰符,则不会观察到对测试的调用,因为调试不会打印任何内容。
我是 RxSwift 的新手。
感谢楼上的@zhongwuzw,看了他的评论我明白了
另一个避免使用 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() 之前打印。
RxSwift 已经添加了这个方法。
看看这个issue
我正在尝试将我对 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() {
}
您可以使用 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)
}
}
输出:
next([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)
}
}
}
输出:
next([])
completed
您应该对 test
函数使用 dynamic
修饰符,编译器永远不会内联或去虚拟化对 test
函数的访问。
像这样:
dynamic func test() {}
我遇到同样的问题后添加此评论,但现在我已经解决了。
我的解决方案 -- 如果这不是您要搜索的内容,我很抱歉,但希望能帮助其他人解决同样的问题 -- 只是为观察到的函数添加 dynamic
修饰符。
这是代码
func viewDidLoad() {
rx.sentMessage(#selector(ViewController.test))
.debug("Test", trimOutput: true)
.subcribe()
.disposed(by: bag)
}
@objc dynamic test() {}
如果没有 dynamic
修饰符,则不会观察到对测试的调用,因为调试不会打印任何内容。
我是 RxSwift 的新手。
感谢楼上的@zhongwuzw,看了他的评论我明白了
另一个避免使用 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() 之前打印。
RxSwift 已经添加了这个方法。 看看这个issue