【问题标题】:what is difference of self in lazy var and var(let) block惰性 var 和 var(let) 块中 self 的区别是什么
【发布时间】:2021-09-13 06:35:11
【问题描述】:

当我使用 let UISwitch 替换 lazy var UISwitch in UITableViewCell 像这样:

let trigger: UISwitch = {
    let sw = UISwitch()
    sw.addTarget(self, action: #selector(onTriggerChanged(sender:)), for: .valueChanged)
    return sw
}()

我发现函数onTriggerChanged 从未调用过,所以我做了一些测试,这是我的测试代码:

class TestCell: UITableViewCell {

    lazy var trigger: UISwitch = {
        let sw = UISwitch()
        print("trigger \(self)")
        sw.addTarget(self, action: #selector(onTriggerChanged(sender:)), for: .valueChanged)
        return sw
    }()
    
    var trigger2: UISwitch = {
        let sw = UISwitch()
        print("trigger2 \(self)")
        sw.addTarget(self, action: #selector(onTriggerChanged(sender:)), for: .valueChanged)
        return sw
    }()

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        let trigger3: UISwitch = {
            let sw = UISwitch()
            print("trigger3 \(self)")
            sw.addTarget(self, action: #selector(onTriggerChanged(sender:)), for: .valueChanged)
            return sw
        }()

        contentView.addSubview(trigger)
        contentView.addSubview(trigger2)
        contentView.addSubview(trigger3)
    }


}

打印消息是:

trigger <TestCell: 0x......>

trigger2 (Function)

trigger3 <TestCell: 0x......>

并且未调用 trigger2 valueChanged 事件。

那么触发器/触发器2/触发器3中的self有什么区别

【问题讨论】:

  • 我收到一条警告,上面写着“字符串插值会为函数值生成调试描述;您的意思是明确说明吗?”在 trigger2 中,这很清楚 self 的含义。你没有得到一个吗?

标签: ios swift


【解决方案1】:

当某个地方需要变量时计算惰性变量,并且仅在非惰性变量时运行一次初始化代码,并在变量初始化时计算值。 onTriggerChanged 函数在哪里。

【讨论】:

    【解决方案2】:

    我确定您知道,self (in the usual sense) is not available in property initialisers of non-lazy properties,这就是您使用lazy 作为解决方法的原因。

    您在 trigger2 中打印的 self 不能引用 self 实例。它实际上是指一个名为self的实例方法,在NSObject中声明,被TestCell继承。

    这实际上是一个实例方法。在 Swift 中,您可以在没有实例的情况下引用实例方法(请记住,您无权访问 actual self 实例)。只是它们的类型变成了(T) -&gt; F,其中T是声明实例方法的类型,F是方法的函数类型。从本质上讲,它们变成了以实例为参数的静态方法,并将原始实例方法返回给您。

    例如,self 方法在没有实例的情况下被引用时,其类型为:

    (TestCell) -> (() -> TestCell)
    

    你可以通过打印出type(of: self)来看到它确实是这样的。

    显然,将self 方法 添加为目标不起作用。无法响应选择器onTriggerChangedWithSender

    对于 trigger1 和 trigger3,self 实例可用的,self 表示通常的东西 - 当前实例。

    【讨论】:

      猜你喜欢
      • 2017-10-28
      • 2022-07-21
      • 2014-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多