无法识别的选择器发送到类

Posted

技术标签:

【中文标题】无法识别的选择器发送到类【英文标题】:Unrecognized selector sent to class 【发布时间】:2017-01-02 14:55:43 【问题描述】:

我已经看到了,这是一个常见问题,但我自己找不到任何解决方案。

代码如下:

class ButtonViewController: UIViewController 

    override func viewDidLoad() 
        super.viewDidLoad()

        view.addSubview(button)
    

    func exmp(sender: UIButton) 
        print("hello world")
    

    let button: UIButton = 
        let but = UIButton(frame: CGRect(x: 33, y: 33, width: 33, height: 33))
        but.setTitle("-", for: .normal)
        but.titleLabel?.textColor = UIColor.white
        but.layer.cornerRadius = 10
        but.backgroundColor = UIColor.red
        but.addTarget(ButtonViewController.self, action: #selector(ButtonViewController.exmp(sender:)), for: .touchDown)
        return but
    

问题: 红色按钮出现,但是当我点击它时,我得到“”错误。

任何帮助表示赞赏!谢谢。

【问题讨论】:

func exmp(sender: UIButton)之前添加@objc 这应该可以工作但是.addTarget(ButtonViewController.self, action: #selector(exmp:), for: .touchDown) 似乎您可以在界面构建器中定义此按钮(并在需要时隐藏它,如果需要) 使用完整的错误消息更新您的问题。您遗漏了“无法识别的选择器”消息的重要部分。 @NSDmitry 添加 '@objc' 也不起作用。对我来说是Command failed due to signal: Segmentation fault: 11。谢谢。 【参考方案1】:

您收到无法识别的选择器发送到类,因为您设置了错误的目标。 目标应该是self 而不是ButtonViewController.self

but.addTarget(self, action: #selector(ButtonViewController.exmp(sender:)), for: .touchDown)

您的#selector 有效,但对于 Swift 3,您应该将操作编写为 func exmp(_ sender: UIButton) ,使选择器 #selector(exmp(_:))。注意:无论你是否重写exmp,你都可以将选择器简化为#selector(exmp)

【讨论】:

我已经在 Swift 上提交了一个与此相关的错误。编译器一方面不应该帮助您使用#selector 语法,但另一方面却让您设置错误的目标。 “无法识别的选择器”应该是死信! 感谢您的回答,但现在有一个不同的问题是“由于信号导致命令失败:分段错误:11”。【参考方案2】:

所以我一直在寻找这个问题 2 天。正确的 addTarget 方法必须是这样的:

but.addTarget(self, action: #selector(ButtonViewController.exmp(sender:)), for: .touchDown)

但是对我来说还有一个问题是“由于信号而导致命令失败:分段错误:11”

当我尝试在 viewDidLoad() 方法中创建我的按钮时,没有错误。所以我认为这可能与按钮的创建位置有关。我在创建按钮时放了 lazy var 而不是 let

不过,作为一个初学者,我真的不知道什么是“layz var”。我只知道这会导致我的按钮被创建,只有在它被调用时。 如果有人能启发我和周围的其他初学者关于惰性变量的知识,那就太好了。谢谢。

最终解决方案

override func viewDidLoad() 
    super.viewDidLoad()

    view.addSubview(button)


func exmp(sender: UIButton) 
    print("hello world")


lazy var button: UIButton = 
    let but = UIButton(frame: CGRect(x: 33, y: 33, width: 33, height: 33))
    but.setTitle("-", for: .normal)
    but.titleLabel?.textColor = UIColor.white
    but.layer.cornerRadius = 10
    but.backgroundColor = UIColor.red
    but.addTarget(self, action: #selector(ButtonViewController.exmp(sender:)), for: .touchDown)
    return but
()

【讨论】:

惰性变量在第一次使用时被初始化。这里重要的原因是 self 在类被初始化之前不可用于属性的初始化。通过使您的 var 变得惰性,您可以通过将该属性的初始化推迟到第一次使用它来绕过该限制。到时候对象会被初始化,self就可以使用了。

以上是关于无法识别的选择器发送到类的主要内容,如果未能解决你的问题,请参考以下文章

Parse 和 Facebook SDK - 发送到类的无法识别的选择器

在 Swift 中使用 NSTimer 时发送到类的无法识别的选择器; NSInvalidArgumentException

DetoxRuntimeError:NSInvalidArgumentException + [UIWindowScene _keyWindowScene]:无法识别的选择器发送到类 0x12dd58

将 Google Map SDK 添加到 iOS6 时将错误无法识别的选择器发送到类

ios Chromecast 发件人:[NSMutableDictionary gck_loadFromCacheWithName:]:无法识别的选择器发送到类 0x1133f1678

Swift:手势识别器无法识别的选择器发送到实例