Swift 获取声明为协议的属性时调用了didSet
下面是一些代码:Swift 获取声明为协议的属性时调用了didSet,swift,protocols,swift2,optional,Swift,Protocols,Swift2,Optional,下面是一些代码: import UIKit protocol ViewModelProtocol { var price: String { get } } class ViewModel: ViewModelProtocol { var price: String { return "$420" } } class ViewController: UIViewController { // If you change the type t
import UIKit
protocol ViewModelProtocol {
var price: String { get }
}
class ViewModel: ViewModelProtocol {
var price: String {
return "$420"
}
}
class ViewController: UIViewController {
// If you change the type to ViewModel directly, no infinite loop
var viewModel: ViewModelProtocol? = nil {
didSet {
print("viewModel didSet called")
updateDisplay()
}
}
required init?(coder aDecoder: NSCoder) {
viewModel = ViewModel()
super.init(coder: aDecoder)
updateDisplay()
}
func updateDisplay() {
print("In updateDisplay()")
print("\(viewModel?.price)")
// if you access the viewModel like this, no infinite loop
// if let v = viewModel {
// print("\(v.price)")
// }
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
此代码将在无限循环中运行。具体来说,它在updateDisplay()
中的print(\(viewModel?.price)
和viewModel
的didSet
之间跳跃
如果直接将viewModel
的类型更改为viewModel
(跳过协议),无限循环将消失。或者,如果在使用前在updateDisplay()
中展开viewModel
,无限循环也会消失
这是在Swift 2中,尽管我还没有验证它是否与早期Swift中的行为相同。另一个数据点是,调用协议上的方法不会导致调用didSet
这对你来说像是一个快速的错误吗?这是一个非常令人印象深刻的案例 这可能是由于协议类型中包含只读属性而导致的willSet属性出现问题。我做了很多测试,很难找到解决方案。但是,如果你真的需要继续这样下去。。。我认为下面的变化可以帮助你
protocol ViewModelProtocol {
var price: String { get set }
}
class ViewModel: ViewModelProtocol {
var price: String {
get {
return "$420"
}
set {
return
}
}
//...
}
正如你所说。。。仅当尝试通过viewModel对象直接访问price属性时,才会出现此问题
我只是把我的答案放在这里,因为它不适合评论字段的大小
但是非常令人印象深刻。。。我将设法找到最终的解决办法。:) 似乎不仅我对didSet{}有这个问题。 对于这个问题,有一个公开的雷达: