即使在 guard self 和非可选属性之后也得到 "Variable 'self.xxx' used before being initialized"
Get a "Variable 'self.xxx' used before being initialized" even after guard self and non optional properties
我目前正在为用 Swift 编写的新应用程序实现 MVVM(使用 Rx)架构,并且在编写 ViewModel 时遇到困难。
这是它的开头:
class GameViewModel {
public let input: Input
public let output: Output
public struct Input {
let slider: AnyObserver<Float>
let buttonCLicked: AnyObserver<Void>
}
public struct Output {
let slider: Observable<Float>
let target: Observable<Int>
let score: Observable<Int>
let round: Observable<Int>
let buttonCLicked: Observable<AlertProperties>
}
private var slider = BehaviorSubject<Float>(value: 0)
private var buttonCLicked = PublishSubject<Void>()
private var target = BehaviorSubject<Int>(value: 0)
private var score = BehaviorSubject<Int>(value: 0)
private var round = BehaviorSubject<Int>(value: 0)
private let disposebag: DisposeBag
private var model: Game!
init(game: Game?) {
disposebag = DisposeBag()
input = Input(slider: slider.asObserver(),
buttonCLicked: buttonCLicked.asObserver())
output = Output(slider: slider.asObservable(),
target: target.asObservable(),
score: score.asObservable(),
round: round.asObservable(),
buttonCLicked: buttonCLicked.map { [weak self] _ in
guard let self = self else {
return AlertProperties(title: "Fail",
message: "!!!",
buttonTitle: "Ok",
handler: nil)
}
return self.getAlertProperties() })
model = game ?? initDefaultGame()
slider.onNext(Float(model.slider))
target.onNext(model.target)
score.onNext(model.score)
round.onNext(model.round)
}
这是一个使用当前值创建对象的基本函数 return:
func getAlertProperties() -> AlertProperties {
guard let targetValue = try? target.value(),
let currentValue = try? slider.value() else {
return AlertProperties(title: "Fail",
message: "!!!",
buttonTitle: "Ok",
handler: nil)
}
// some code
return AlertProperties(title: title,
message: "\(points) points: \(castCurrentValue)",
buttonTitle: "Ok",
handler: {
self.target.onNext(self.getRandomValue())
self.slider.onNext(50.0)
})
}
我在这里要做的是在我的初始化函数上注册我的输入和输出。对于输出部分,我想传输具有一些当前值的函数的结果 (getAlertProperties)。
基本上我的 ViewController 上有一个触发器,当用户单击一个简单的按钮时,它需要这些值显示在 AlertController 中。
我在输出中收到关于 buttonClicked 声明的错误消息 Variable 'self.xxx' used before initialized。我知道我需要初始化每个非可选属性在使用 self 之前,但我认为也许使用守卫可以解决问题。显然不是...
如何在不使属性 input 和 output 可选的情况下解决此问题?
谢谢
好的,我将我的属性输入和输出设置为惰性的并且它起作用了。
static let errorAlertProperties = AlertProperties(title: "Fail",
message: "!!!",
buttonTitle: "Ok",
handler: nil)
lazy var input = Input(slider: slider.asObserver(),
buttonCLicked: buttonCLicked.asObserver(),
resetCLicked: resetClicked.asObserver())
lazy var output = Output(slider: slider.asObservable(),
target: target.asObservable(),
score: score.asObservable(),
round: round.asObservable(),
buttonCLicked: buttonCLicked.map { [weak self] _ in
guard let self = self else {
return GameViewModel.errorAlertProperties
}
return self.getAlertProperties() })
我不知道这是否是 "right" 的方法,如果您有更好的方法,请告诉我。
谢谢
我目前正在为用 Swift 编写的新应用程序实现 MVVM(使用 Rx)架构,并且在编写 ViewModel 时遇到困难。
这是它的开头:
class GameViewModel {
public let input: Input
public let output: Output
public struct Input {
let slider: AnyObserver<Float>
let buttonCLicked: AnyObserver<Void>
}
public struct Output {
let slider: Observable<Float>
let target: Observable<Int>
let score: Observable<Int>
let round: Observable<Int>
let buttonCLicked: Observable<AlertProperties>
}
private var slider = BehaviorSubject<Float>(value: 0)
private var buttonCLicked = PublishSubject<Void>()
private var target = BehaviorSubject<Int>(value: 0)
private var score = BehaviorSubject<Int>(value: 0)
private var round = BehaviorSubject<Int>(value: 0)
private let disposebag: DisposeBag
private var model: Game!
init(game: Game?) {
disposebag = DisposeBag()
input = Input(slider: slider.asObserver(),
buttonCLicked: buttonCLicked.asObserver())
output = Output(slider: slider.asObservable(),
target: target.asObservable(),
score: score.asObservable(),
round: round.asObservable(),
buttonCLicked: buttonCLicked.map { [weak self] _ in
guard let self = self else {
return AlertProperties(title: "Fail",
message: "!!!",
buttonTitle: "Ok",
handler: nil)
}
return self.getAlertProperties() })
model = game ?? initDefaultGame()
slider.onNext(Float(model.slider))
target.onNext(model.target)
score.onNext(model.score)
round.onNext(model.round)
}
这是一个使用当前值创建对象的基本函数 return:
func getAlertProperties() -> AlertProperties {
guard let targetValue = try? target.value(),
let currentValue = try? slider.value() else {
return AlertProperties(title: "Fail",
message: "!!!",
buttonTitle: "Ok",
handler: nil)
}
// some code
return AlertProperties(title: title,
message: "\(points) points: \(castCurrentValue)",
buttonTitle: "Ok",
handler: {
self.target.onNext(self.getRandomValue())
self.slider.onNext(50.0)
})
}
我在这里要做的是在我的初始化函数上注册我的输入和输出。对于输出部分,我想传输具有一些当前值的函数的结果 (getAlertProperties)。 基本上我的 ViewController 上有一个触发器,当用户单击一个简单的按钮时,它需要这些值显示在 AlertController 中。
我在输出中收到关于 buttonClicked 声明的错误消息 Variable 'self.xxx' used before initialized。我知道我需要初始化每个非可选属性在使用 self 之前,但我认为也许使用守卫可以解决问题。显然不是...
如何在不使属性 input 和 output 可选的情况下解决此问题?
谢谢
好的,我将我的属性输入和输出设置为惰性的并且它起作用了。
static let errorAlertProperties = AlertProperties(title: "Fail",
message: "!!!",
buttonTitle: "Ok",
handler: nil)
lazy var input = Input(slider: slider.asObserver(),
buttonCLicked: buttonCLicked.asObserver(),
resetCLicked: resetClicked.asObserver())
lazy var output = Output(slider: slider.asObservable(),
target: target.asObservable(),
score: score.asObservable(),
round: round.asObservable(),
buttonCLicked: buttonCLicked.map { [weak self] _ in
guard let self = self else {
return GameViewModel.errorAlertProperties
}
return self.getAlertProperties() })
我不知道这是否是 "right" 的方法,如果您有更好的方法,请告诉我。
谢谢