问题
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