可观察的选择器 - RxSwift

Posted

技术标签:

【中文标题】可观察的选择器 - RxSwift【英文标题】:Observable for selector - RxSwift 【发布时间】:2016-09-26 17:01:10 【问题描述】:

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


【问题讨论】:

这可能是因为self 不是NSObject。如果您能提供帮助,我不建议您使用sentMessage。就像你看到的那样,它的行为可能很奇怪,充其量只是一种代码味道。仅在必要时使用。 @solidcell 感谢您的设置让我更加理解! 【参考方案1】:

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

输出:

下一个([]) 完成

【讨论】:

感谢您的回答!但是你能解释一下我在上面添加的例子中做错了什么吗?我将不胜感激!【参考方案2】:

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

像这样: dynamic func test()

【讨论】:

【参考方案3】:

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

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

这是代码

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


@objc dynamic test() 

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

我是 RxSwift 的新手。

谢谢上面的@zhongwuzw,看了他的评论我明白了。

【讨论】:

【参考方案4】:

另一个避免使用 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() 之前打印。

【讨论】:

【参考方案5】:

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

【讨论】:

以上是关于可观察的选择器 - RxSwift的主要内容,如果未能解决你的问题,请参考以下文章

RxSwift MVVM 如何使用项目管理器设置视图模型?

iOS RxSwift - 如何“断开”一个 observable?

处置(取消)可观察的。 SubscribeOn 和 observeOn 不同的调度器

如何在 RxSwift 中观察 UITableView 点击/选择的先前值和当前值?

RxSwift - Observable 移除使用过的元素

为啥我使用有效的 withLatestFrom 操作从选择器获取具有动作观察者属性的对象?