以编程方式将目标添加到按钮会引发错误 "unrecognized selector sent to class"

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

不确定为什么当我尝试使用我在代码中创建的按钮时收到 "Unrecognized selector sent to class" 错误。

这是我的代码:

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

其实我刚想出来

出于某种原因,将 'let' 替换为 'lazy var' 似乎可以解决问题。我无法解释它为什么有效,但它确实有效。

其实都是时间问题。您正在声明一个实例 属性 以及一个初始化该 属性 的定义和调用函数,然后您继续在该函数中说 button.addTarget(self...。那么问题是:那个函数的代码什么时候会运行?令人难以置信的是,这非常重要,以至于它实际上改变了 self.

的含义

当你说let做出这个声明时,代码运行s在实例还不存在的时候。实例正是我们在那一刻正在形成的过程中;还没有 "cooked"。事实上,你不知道的是,self 在那一刻意味着 UIButton class! 因此生成的目标操作是无效的;你没有 class 方法 postComment;这是一个实例方法(正确)。所以稍后当你点击按钮并且我们尝试对 class 说 postComment 时,我们崩溃了。 "Unrecognized selector sent to class",正如你所说。

另一方面,当您说 lazy var 时,直到实例 self 确实存在后才会调用代码,self 表示实例,一切都很好。

初学者和非初学者都非常困惑;即使在指出问题之后,我自己也犯了完全相同的错误。在我看来,编译器应该抓住这个并阻止你,但它没有。我已提交错误:http://bugs.swift.org/browse/SR-4865