Here is the code:
import UIKit
protocol ViewModelProtocol {
var price: String { get }
}
class ViewModel: ViewModelProtocol {
var price: String {
return "$420"
}
}
class ViewController: UIViewController {
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)")
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
This code will run in an infinite loop. In particular, it bounces between print("\(viewModel?.price)")in updateDisplay()and didSetfor viewModel.
If you change the type viewModelto viewModeldirectly (skipping the protocol), the infinite loop disappears. Alternatively, if you expand viewModelin updateDisplay()before using it, an endless loop will also disappear.
This is in Swift 2, although I have not tested to see if it has the same behavior in earlier Swift. Another data point that invokes methods in the protocol does not invoke a call didSet.
Does this sound like a Swift bug for you?