Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
716 views
in Technique[技术] by (71.8m points)

ios - what is difference of self in lazy var and var(let) block

when I use let UISwitch replace lazy var UISwitch in UITableViewCell like this:

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

I found the function onTriggerChanged never called, so I do some test, here is my test code:

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)
    }


}

print message is:

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

trigger2 (Function)

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

and trigger2 valueChanged event not called.

so what difference of self in trigger/trigger2/trigger3

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I'm sure you're aware, self (in the usual sense) is not available in property initialisers of non-lazy properties, which is why you use lazy as a workaround.

The self that you are printing in trigger2 can't refer to the self instance. It actually refers to an instance method called self, declared in NSObject, which is inherited by TestCell.

This is actually an instance method. In Swift, you are allowed to refer to instance methods without having an instance (remember that you don't have access to the actual self instance here). It's just that their type becomes (T) -> F, where T is the type in which the instance method is declared, and F is the function type for the method. Essentially, they become static methods that take an instance as parameter, and give you back the original instance method.

For example, the self method, when referenced without an instance, would have the type:

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

You can see that is indeed what it is by printing out type(of: self).

Clearly, adding the self method as the target doesn't work. It can't respond to the selector onTriggerChangedWithSender.

For trigger1 and trigger3, the self instance is available, and self mean the usual thing - the current instance.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...