【问题标题】:Protocol-Oriented Programming Extension variable init twice面向协议的编程扩展变量初始化两次
【发布时间】:2017-01-13 03:01:51
【问题描述】:

情况是这样的。我有一个协议和它的扩展。

protocol CustomViewAddable {
    var aView: UIView { get }
    var bView: UIView { get }
    func setupCustomView()
}
extension CustomViewAddable where Self: UIViewController {
    var aView: UIView {
        let _aView = UIView()
        _aView.frame = self.view.bounds
        _aView.backgroundColor = .grey
        // this is for me to observe how many times this aView init. 
        print("aView: \(_aView)")
        return _aView
    }
    var bView: UIView {
        let _bView = UIView(frame: CGRect(x: 30, y: 30, width: 30, height: 30))
        _bView.backgroundColor = .yellow
        return _bView
    }
    func setupCustomView() {
        view.addSubview(aView);
        aView.addSubview(bView);
    }
}

我制作了一个 ViewController 来符合这个协议,然后我将这个自定义的“aView”添加到我的 ViewController 的视图中。

class MyVC: UIViewController, CustomViewAddable {
    override func viewDidLoad() {
        super.viewDidLoad()

        setupCustomView()
    }
}

我运行它。在我的控制台日志中,它打印了两次 init,我试图在我的自定义“aView”中做某事,但它失败了。 (我在上面粘贴的代码我简化了,这样很容易显示我的意图)

谁能解释原因或修复它,我将不胜感激。

【问题讨论】:

  • 你的意思是你的print("aView: \(_aView)") 会打印两次?

标签: swift swift-protocols protocol-extension protocol-oriented


【解决方案1】:

因为您的var aView: UIView 是计算变量而不是存储变量,

所以每次调用aView,都会创建一个新的UIView

您可以在NSObject 中使用Associated Objects,这里有一些教程:

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    基本上,在您实现setupCustomView 方法的方式中,没有任何东西可以工作,因为正如另一个回复中提到的,您使用的是计算属性,因此这意味着每次访问该属性时都会再次创建它。

    你不需要使用关联对象或类似的东西来实现你想要的,你只需要在开始时保留aView的引用,避免再次调用它,这样:

    func setupCustomView() {
       let tView = aView // only is computed once
       view.addSubview(tView)
       tView.addSubview(bView)
    }
    

    希望对你有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-12
      • 2016-07-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多