带有 UIView 子类的惰性属性

Posted

技术标签:

【中文标题】带有 UIView 子类的惰性属性【英文标题】:Lazy property with UIView subclass 【发布时间】:2017-07-27 03:37:08 【问题描述】:

我想添加UIView子类属性懒初始化,例如:

import UIKit

class MyView: UIView 

class Controller: UIViewController 

    lazy var myView = MyView()

但我有一个错误:

无法将值类型“UIView”转换为指定类型“MyView” 我可以用属性类型修复错误:

lazy var myView: MyView = MyView()

或将初始化更改为:

let myView = MyView()

但是为什么 Swift 不能推断类型呢?

【问题讨论】:

如果我调用 UIView 初始化程序之一 lazy var myView = MyView(frame: .zero) 也可以工作。原来的问题仍然存在...... @kennytm,好话,谢谢! 不知道为什么,但您需要调用指定的初始化程序才能使其正常工作。 【参考方案1】:

如果你被初始化为一个标记为惰性的变量,重要的是提供一个类型。

  lazy var myView:MyView = MyView()

【讨论】:

为什么?给我看证据! 当你使用惰性时,实际值是通过评估创建的,所以你需要预先声明它的数据类型。你可以检查它hackingwithswift.com/example-code/language/… 但是为什么在这种情况下我可以提交类型:lazy var myView = UIView()【参考方案2】:

我尝试使用自定义类来复制问题。并没有发现任何问题。

需要注意的一点是,当惰性属性没有自定义时(示例中的 defaultValue)编译器没有要求我提供显式类型。 但 对于自定义属性 (redView),我必须提供显式类型。 如果我没有提供明确的类型,这就是我得到的。

无法推断复杂的闭包返回类型;添加显式类型 消除歧义

这已经说得很清楚了,闭包的返回类型不能被推断出来。这似乎很明显,因为我们使用的闭包没有明确的返回类型。

所以我尝试提供一个具有显式类型的闭包,我期待现在我不需要为 redView lazy 属性提供显式类型。正如预期的那样,它在不提供惰性属性的类型的情况下工作。

【讨论】:

你说的是闭包。但我只使用了默认初始化的子类。【参考方案3】:

如果您为 MyView 提供 init,那么就可以了。但是为什么呢?花了几个小时想通了,结果是?,等高手解答。

class MyView: UIView 
    init() 
        super.init(frame: .zero)
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

【讨论】:

是的,也适用于kennytm example

以上是关于带有 UIView 子类的惰性属性的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式使用自动布局实现带有子视图的 uiview 子类

带有协议问题的 Swift Generic UIView 子类

带有 UIView 子类的 UITableViewCell 在单元格上创建多个图层

UIView 的子类没有视图属性

将带有 xib 的 UIView 子类添加到 UIViewController

如何在 SwiftUI 视图中访问 UIView 子类的属性?