I'm trying to migrate my FRP understanding from ReactiveCocoa 2.5 to RxSwift and I have one misunderstanding. In ReactiveCocoa, I used rac_signalForSelector
when I wanted to observe an invocation of a method. Is there any way to implement this logic using RxSwift?
I wrote a small example in which I want to dispose a subscription when the test
method invokes. But in the subscribe block I can still see a next(6)
event. What am I doing wrong?
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() {
}
You can use 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)
}
}
Outputs:
next([0])
Or another example:
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)
}
}
}
Outputs:
next([])
completed
you should use dynamic
modifier for test
function that access to test
function is never inlined or devirtualized by the compiler.
like this: dynamic func test() {}
I am adding this comment after encounter the same problem but now I've solved it.
The solution for me, -- I am sorry if this is not the thing you search for but hope will help others with the same issue --, was just adding dynamic
modifier for the observed function.
This is the code
func viewDidLoad() {
rx.sentMessage(#selector(ViewController.test))
.debug("Test", trimOutput: true)
.subcribe()
.disposed(by: bag)
}
@objc dynamic test() {}
Without dynamic
modifier the call to test isn't observed because the debug doesn't print anything.
I am new to RxSwift.
Thanks @zhongwuzw above, I got the idea after read his comment.
Another solution, which avoids using sentMessage, is to define a testSubject and trigger a next event on it in your test function.
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(())
}
This will only print until test() is called.
RxSwift has Already added this method. look at this issue
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.