初始化具有多个依赖项的 RAC ReactiveSwift 属性?
Initializing a RAC ReactiveSwift Property that has multiple dependencies?
我对使用 ReactiveSwift 和 ReactiveCocoa 还很陌生,我似乎遇到了有关初始化具有依赖项的 属性 的正确方法的障碍。
例如,在下面的代码中,我尝试初始化一个 属性,但我得到了预期的编译器错误。我的问题是如何/什么是 "correct" 方法来做到这一点。
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 [=11=] && self.dependency2.value == "dependency2" && self.dependency3.value == 12345 {
return ""
}
return ""
}
}
}
因此,正如您在上面的评论中可能已经注意到的那样,我想知道是否有一种方法可以使用 ReactiveSwift 来处理这种情况,而不是我上面提到的那些并不是真正理想的解决方案。
适合该场景的工具是 combineLatest
,它会在更新任何这些属性(流)时提供所有这些属性(流)的组合版本。
weightLabel = Property.combineLatest(dependency, dependency2, dependency3)
.map { d1, d2, d3 in
return "Hello World! \(d1) \(d2) \(d3)"
}
关于编译器错误,问题是在初始化每个存储的 属性 之前,您在闭包中 capturing/referring 到 self
。根据意图,您可以使用 捕获列表 直接捕获您感兴趣的值和对象 w/o 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) }
}
我对使用 ReactiveSwift 和 ReactiveCocoa 还很陌生,我似乎遇到了有关初始化具有依赖项的 属性 的正确方法的障碍。
例如,在下面的代码中,我尝试初始化一个 属性,但我得到了预期的编译器错误。我的问题是如何/什么是 "correct" 方法来做到这一点。
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 [=11=] && self.dependency2.value == "dependency2" && self.dependency3.value == 12345 {
return ""
}
return ""
}
}
}
因此,正如您在上面的评论中可能已经注意到的那样,我想知道是否有一种方法可以使用 ReactiveSwift 来处理这种情况,而不是我上面提到的那些并不是真正理想的解决方案。
适合该场景的工具是 combineLatest
,它会在更新任何这些属性(流)时提供所有这些属性(流)的组合版本。
weightLabel = Property.combineLatest(dependency, dependency2, dependency3)
.map { d1, d2, d3 in
return "Hello World! \(d1) \(d2) \(d3)"
}
关于编译器错误,问题是在初始化每个存储的 属性 之前,您在闭包中 capturing/referring 到 self
。根据意图,您可以使用 捕获列表 直接捕获您感兴趣的值和对象 w/o 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) }
}