swift - 获取声明为协议(protocol)的属性时调用 didSet

标签 swift protocols swift2 option-type

这是一些代码:

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(跳过协议(protocol)),无限循环就会消失。或者,如果您在使用 updateDisplay() 之前打开 viewModel,无限循环也会消失。

这是在 Swift 2 中的,尽管我还没有验证它在早期的 Swift 中是否有相同的行为。另一个数据点,调用协议(protocol)上的方法不会导致调用 didSet

你觉得这像是 Swift 的 bug 吗?

最佳答案

看来不止我有didSet{}这个问题。 此问题有公开雷达:https://openradar.appspot.com/22574299

关于swift - 获取声明为协议(protocol)的属性时调用 didSet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32705627/

相关文章:

ios - 如何使用 panGesture 从 firstViewController 的顶部移动 secondViewController?

ios - iOS 9 中弃用了 sendAsynchronousRequest

swift - 两个 NSDate 的计算差异是错误的 - 已修复

uinavigationcontroller - shouldAutorotate 不适用于导航 Controller swift 2

ios - tapGesture 超链接 swift

ios - UIView setImage :]: unrecognized selector sent to instance

ios - 如何在 iOS 应用程序中使用 Wordpress REST API?

swift - Swift 中所有 IntegerLiteralConvertible 的通用 init 函数

ios - 在 UIPageViewController 中以编程方式转到下一页

ios - 可在其他类中访问的 Objective-C 变量