Adding a target to a button programmatically throws an error “unrecognized selector sent to class”

让人想犯罪 __ 提交于 2021-02-04 14:19:05

问题


Not sure why I am getting an "Unrecognized selector sent to class" error when I try to use the button I've created in code.

Here is my code:

let sendButton: UIButton = {
        let button = UIButton(type: .system)
        button.setTitle("Send", for: .normal)
        button.setTitleColor(UIColor.white, for: .normal)
        button.backgroundColor = #colorLiteral(red: 0.5098039216, green: 0.5215686275, blue: 0.8392156863, alpha: 1)
        button.layer.cornerRadius = 5
        button.isUserInteractionEnabled = true
        button.addTarget(self, action: #selector(postComment), for: .touchUpInside)
        return button
    }()

回答1:


It's actually all a matter of timing. You are declaring an instance property along with a define-and-call function that initializes that property, and you proceed to say button.addTarget(self... in that function. The question then is: when will that function's code run? Incredibly, that matters a lot, so much so that it actually changes the meaning of self.

When you say let to make this declaration, the code runs at a time when the instance does not yet exist. The instance is exactly what we are in the process of forming at that moment; it isn't "cooked" yet. In fact, unbeknownst to you, self at that moment means the UIButton class! Therefore the resulting target-action is invalid; you have no class method postComment; it's an instance method (rightly). And so later on when you tap the button and we try to say postComment to the class, we crash. "Unrecognized selector sent to class", exactly as you say.

On the other hand, when you say lazy var, the code is not called until after the instance self does exist, self means the instance, and all is well.

It's terribly confusing to beginners, and to not-so-beginners; even after pointing out the problem, I've proceeded to make exactly the same mistake myself. In my opinion the compiler should catch this and stop you, but it doesn't. I've filed a bug: http://bugs.swift.org/browse/SR-4865




回答2:


I actually Just figured it out.

For some reason, replacing 'let' with 'lazy var' seems to do the trick. I can't explain why it works, but it does.



来源:https://stackoverflow.com/questions/50662302/adding-a-target-to-a-button-programmatically-throws-an-error-unrecognized-selec

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!