【发布时间】:2015-09-21 22:39:41
【问题描述】:
这里有一些代码:
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(跳过协议),死循环就消失了。或者,如果您在使用之前将viewModel 解包到updateDisplay() 中,则无限循环也会消失。
这是在 Swift 2 中,虽然我还没有验证它在早期的 Swift 中是否具有相同的行为。另一个数据点,在协议上调用方法不会导致调用didSet。
在你看来,这看起来像一个 Swift 错误吗?
【问题讨论】:
标签: swift protocols swift2 optional