当前位置: 首页 > 面试题库 >

Swift:使用协议扩展会导致“无法识别的选择器发送到实例”

能可人
2023-03-14
问题内容

我试图在所有符合协议的UIViewControllers中添加点按功能MyProtocol

以下是我的做法:

import UIKit

protocol MyProtocol: class{
    var foo: String? {get set}
    func bar()
}


extension MyProtocol where Self: UIViewController {
    func bar() {
        print(foo)
    }
}


class TestViewController: UIViewController, MyProtocol{
    var foo: String?

    override func viewDidLoad() {
        super.viewDidLoad()

        foo = "testing"
        let tapGesture = UITapGestureRecognizer(target: self, action: "bar")
}

点击屏幕时,结果如下:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: unrecognized selector sent to instance

我了解此错误,但不知道如何解决。谁能建议如何做到这一点?


问题答案:

问题在于,Objective-C不了解协议扩展。因此,您不能使用协议扩展将方法注入到类中,而Objective-
C的消息传递机制可以看到该方法。您需要bar在视图控制器类 本身中 声明。

(我意识到这正是您要避免这样做的方法,但是我无能为力。)

一种解决方法可能是这样的:

override func viewDidLoad() {
    super.viewDidLoad()

    foo = "testing"
    let tapGesture = UITapGestureRecognizer(target: self, action: "baz")
    self.view.addGestureRecognizer(tapGesture)
}

func baz() {
    self.bar()
}

现在,我们使用Objective-
C的消息传递机制进行调用baz,然后使用Swift的消息传递机制进行调用bar,这当然是有效的。我意识到它并不像您想的那样干净,但是至少现在实现bar可以在协议扩展中使用。

(当然,另一种解决方案是做在协议扩展存在之前我们所做的事情:使所有视图控制器都从包含的一些通用自定义UIViewController子类继承bar。)



 类似资料:
  • 问题内容: 对于我的s ,我有一个非常简单的协议扩展,它具有通过轻击手势关闭键盘的功能。这是我的代码: 问题是上面的代码在此行上引发了编译错误: 带有错误信息: “ #selector”的参数引用实例方法“ on(tap :)”,而该方法未公开给Objective-C 并建议在“ 之前”添加“修复” 好的,我添加标签: 但是,随后,它在此新添加的标记上引发了不同的编译错误,并显示错误消息: @ob

  • 问题内容: 每当我尝试更新核心数据模型的值时,我都会不断收到此错误。这是我的模特 这是我的代码tableViewCell 我不断收到错误消息 “由于未捕获的异常’NSInvalidArgumentException’而终止应用程序,原因:’-[Habit setTrackingType:]:无法识别的选择器发送到实例0x7fdcbb002c90’” 在self.habit?.trackingTyp

  • 问题内容: 我已经以编程方式创建了并添加到其中: 但是当我触摸视图时,Xcode抛出错误: 2016-07-13 09:24:29.918 Draft_Hypa_02 [661:83024]-[Draft_Hypa_02.ViewController handleTap:]:无法识别的选择器已发送到实例0x17d94a10 2016-07-13 09:24:29.921 Draft_Hypa_02

  • 问题内容: 我在尝试让用户按下UIButton时遇到问题。我不断收到错误消息:无法识别的选择器已发送到实例 对于Swift方法,例如传递给选择器方法的正确字符串是什么?是“ buttonClick”,“ buttonClick:”,“ buttonClickSender:”还是其他? 问题答案: 您正在对该操作使用无效的方法签名。您正在提供,但该方法有一个参数,因此签名应为 有关如何设置选择器格式

  • 问题内容: 我看不到以下按钮为何引发错误:2014-08-13 00:29:57.674 view1 [26581:842344]-[view1.ViewController buttonAction:]:无法识别的选择器已发送至实例0x797731c0 2014-08-13 00:29:57.677 view1 [26581:842344] * 由于未捕获的异常’NSInvalidArgumen

  • 问题内容: 我正在尝试从字典中获取特定键的值,但我得到了一个[[__NSCFArray objectForKey:]:无法识别的选择器发送到实例” 我NSLog我的头像字典,我的结果是: 问题答案: 问题是您没有。的计数为1,并包含。 要遍历数组中的所有项目,请枚举数组。 注意:我也从[]语法切换到了。我比较喜欢