信号观察者可以访问 ReactiveCocoa 信号的最后发出的值吗?

Dir*_*nry 4 reactive-programming ios reactive-cocoa swift reactive-cocoa-5

我开始使用 ReactiveCocoa,但仍然在一些基本概念上苦苦挣扎:

  1. 我的应用程序开始侦听地理位置数据(init在我的视图模型中)
  2. 我的应用程序发出带有我当前位置的信号(didFindCurrentPosition被调用)
  3. 我的视图控制器显示地图加载(viewDidLoad在我的视图控制器中)
  4. 我的视图控制器开始观察当前位置信号(仍然viewDidLoad

我的问题是:完成步骤 2 后,如果信号上没有发送其他事件,我的视图控制器不会收到通知。

我的视图控制器如何访问信号的最后一个值?(即如何在步骤 3 中访问步骤 2 中发出的值?)

感谢您的帮助。

PS:ReactiveCocoa 看起来像一个很棒的库,但我对文档的状态感到困惑。恕我直言,它不是很清楚,并且缺乏一些关于如何使用它的明确指南。

代码

视图模型:

class MyViewModel: LocationManagerDelegate {
    let locationManager: LocationManager
    let geolocationDataProperty = MutableProperty<Geolocation?>(nil)
    let geolocationData: Signal<Geolocation?, NoError>

    init() {
        geolocationData = geolocationDataProperty.signal

        // Location Management
        locationManager = LocationManager()
        locationManager.delegate = self
        locationManager.requestLocation()
    }

    // MARK: - LocationManagerDelegate

    func didFindCurrentPosition(location: CLLocation) {
        geolocationDataProperty.value = Geolocation(location: location)
    }
}
Run Code Online (Sandbox Code Playgroud)

视图控制器:

class MyViewController: UIViewController {
    let viewModel = MyViewModel()

    init() {
        super.init(nibName: nil, bundle: nil)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        viewModel.geolocationData
            .observe(on: UIScheduler())
            .observeValues { geolocation in
                debugPrint("GOT GEOLOCATION")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

gka*_*kas 5

您已经拥有一个Property保存最新发出值的 。不要使用属性,而是signal使用producer. 这样,当您启动时,producer您将首先获得当前值(如果没有发送,您将获得零)。

\n\n

比照。文档

\n\n
\n

属性的当前值可以从值获取器获取。生产者 getter 返回一个信号生产者,该信号生产者将发送 property\xe2\x80\x99s 当前值,然后随时间推移发送所有更改。信号获取器返回一个信号,该信号将发送随时间变化的所有更改,但不发送初始值

\n
\n\n

因此,对于问题中的代码,该viewDidLoad方法应该执行如下操作:

\n\n
viewModel.geolocationDataProperty\n        .producer\n        .start(on: UIScheduler())\n        .startWithValues { geolocation in\n            debugPrint("GOT GEOLOCATION")\n    }\n
Run Code Online (Sandbox Code Playgroud)\n