【问题标题】:Initializing a RAC ReactiveSwift Property that has multiple dependencies?初始化具有多个依赖项的 RAC ReactiveSwift 属性?
【发布时间】:2017-09-16 07:15:39
【问题描述】:

我对使用 ReactiveSwift 和 ReactiveCocoa 还很陌生,我似乎在初始化具有依赖关系的属性的正确方法方面遇到了障碍。

例如在下面的代码中,我尝试初始化一个属性,但我得到一个预期的编译器错误。我的问题是如何/什么是“正确”的方式来做到这一点。

class SomeViewModel {
// illustration purposes, in reality the property (dependency) we will observe will change over time
let dependency = Property(value: true)
let dependency2 = Property(value: "dependency2")
let dependency3 = Property(value: 12345)
let weightLabel: Property<String>

// private(set) var weightLabel: Property<String>!
// using private(set) var weightLabel: Property<String>! works, 
// however this changes the meaning behind using let, because we could
// reinitalize weightLabel again which is not similar to using a let so not a good alternative

// let weightLabel: Property<String> = Property(value: "")
// another solution that will work but will result in a wrong value
// upon initalization then, changed into the "correct value" thus, i
// am discrading this as well

init() {
    weightLabel = dependency.map {
        // compiler error, 'self' captured by closure before all members were initalized. 
        // My question is if there is a way to handle this scenario properly
        if $0 && self.dependency2.value == "dependency2" && self.dependency3.value == 12345 {
            return ""
        }
        return ""
    }
}
}

因此,正如您在上面的 cmets 中可能已经注意到的那样,我想知道是否有一种方法可以使用 ReactiveSwift 来处理这种情况,而不是我上面提到的那些并不是真正理想的解决方案。

【问题讨论】:

    标签: ios swift mvvm reactive-cocoa reactive-swift


    【解决方案1】:

    适合该场景的工具是combineLatest,它提供所有这些属性(流)的组合版本,只要它们中的任何一个被更新。

    weightLabel = Property.combineLatest(dependency, dependency2, dependency3)
        .map { d1, d2, d3 in
            return "Hello World! \(d1) \(d2) \(d3)"
        }
    

    关于编译器错误,问题是您在初始化每个存储属性之前在闭包中捕获/引用self。根据意图,您可以使用 捕获列表 直接捕获您感兴趣的值和对象,而无需 self

    let title: String
    let action: () -> Void
    
    init() {
        title = "Hello World!"
    
        // ? `action` has not been initialised when `self` is
        // being captured.
        action = { print(self.title) } 
    
        // ✅ Capture `title` directly. Now the compiler is happy.
        action = { [title] in print(title) }
    }
    

    【讨论】:

    • 甜蜜!感谢您的详细解释! :)
    猜你喜欢
    • 1970-01-01
    • 2021-10-09
    • 2012-07-25
    • 1970-01-01
    • 2017-11-29
    • 1970-01-01
    相关资源
    最近更新 更多