使用选择器错误的Swift 3协议扩展 [英] Swift 3 protocol extension using selector error

查看:217
本文介绍了使用选择器错误的Swift 3协议扩展的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为我的 UIViewController 是一个非常简单的协议扩展,提供了通过点按手势解除键盘的功能。这是我的代码:

I have what I thought to be a very simple protocol extension for my UIViewControllers providing the capability to dismiss a keyboard through a tap gesture. Here's my code:

@objc protocol KeyboardDismissing { 
    func on(tap: UITapGestureRecognizer)
}

extension KeyboardDismissing where Self: UIViewController {

    func addDismissalGesture() {
        let tap = UITapGestureRecognizer(target: self, action: #selector(Self.on(tap:)))
        view.addGestureRecognizer(tap)
    }

    func on(tap: UITapGestureRecognizer) {
        dismissKeyboard()
    }

    func dismissKeyboard() {
        view.endEditing(true)
    }
}

问题是上面的代码在这一行引发编译错误:

The problem is that the above code throws a compile error on this line:

let tap = UITapGestureRecognizer(target: self, action: #selector(Self.on(tap:)))

使用错误消息:


'#selector'的参数是指没有暴露给Objective的实例方法'on(tap :)' - C

Argument of '#selector' refers to instance method 'on(tap:)' that is not exposed to Objective-C

建议通过添加 @objc 来修复它 func on(tap:UITapGestureRecognizer)

with the suggestion to "fix it" by adding @objc before func on(tap: UITapGestureRecognizer)

好的,我添加标签:

@objc func on(tap: UITapGestureRecognizer) {
    dismissKeyboard()
}

但是,它会在这个新添加的 @objc 标记上抛出不同的编译错误,并显示错误消息:

But then, it throws a different compile error on this newly added @objc tag with the error message:


@objc只能用于类成员,@ objc协议和类的具体扩展

@objc can only be used with members of classes, @objc protocols, and concrete extensions of classes

建议通过删除我刚刚被告知添加的完全相同的标签来修复它。

with the suggestion to "fix it" by removing the exact same tag I was just told to add.

我最初想在我的协议定义解决任何 #selector @objc >问题但显然情况并非如此,这些周期性的错误信息/建议丝毫没有帮助。我到处乱哄哄地追加 @objc 标签,将方法标记为可选,放协议定义中的方法等。

I originally thought adding @objc before my protocol definition would solve any #selector problems but apparently that's not the case, and these cyclical error messages/suggestions aren't helping in the slightest. I've gone down a wild goose chase of adding/removing @objc tags everywhere, marking methods as optional, putting methods in the protocol's definition, etc.

我在协议定义中放入的内容也无关紧要让扩展名保持不变,以下示例不起作用也不起作用协议定义中声明方法的任意组合:

It also doesn't matter what I put in the protocol definition Leaving the extension the same, the following example does not work nor does any combination of the declared methods in the protocol's definition:

@objc protocol KeyboardDismissing { 
    func on(tap: UITapGestureRecognizer)
}

这让我觉得它可以通过编译作为一个独立的协议来工作,但第二次我尝试将其添加到视图控制器:

This tricks me into thinking it works by compiling as a stand alone protocol, but the second I try to add it to a view controller:

class ViewController: UIViewController, KeyboardDismissing {}

它吐出原始错误。

有人可以解释一下我做错了怎么可以编译呢?

Can someone explain what I'm doing wrong and how I can compile this?

注意:

我看了这个问题但它是针对Swift 2.2而不是Swift 3,一旦你创建一个继承自示例中定义的协议的视图控制器类,答案就会编译。

I've looked at this question but it is for Swift 2.2 not Swift 3 nor does the answer compile as soon as you create a view controller class that inherits from the protocol defined in the example.

我'我还看了这个问题,但答案使用 NotificationCenter 这不是我想要的。

I've also looked at this question but the answer uses NotificationCenter which is not what I'm after.

如果还有其他看似重复的问题,请告诉我。

If there are any other seemingly duplicate questions, please let me know.

推荐答案

这是一个Swift协议扩展。 Swift协议扩展对于Objective-C是不可见的,无论如何;它对它们一无所知。但是 #selector 是关于Objective-C查看和调用你的函数。这不会发生,因为您的 on(tap:)函数在协议扩展中仅定义 。因此编译器正确地阻止了你。

This is a Swift protocol extension. Swift protocol extensions are invisible to Objective-C, no matter what; it knows nothing of them. But #selector is about Objective-C seeing and calling your function. That is not going to happen because your on(tap:) function is defined only in the protocol extension. Thus the compiler rightly stops you.

这个问题是一大类问题之一,人们认为通过尝试处理Cocoa时,他们会很聪明地使用协议扩展通过协议扩展将Objective-C可调用功能(选择器,委托方法,等等)注入到类中。这是一个吸引人的想法,但它不会起作用。

This question is one of a large class of questions where people think they are going to be clever with protocol extensions in dealing with Cocoa by trying to inject Objective-C-callable functionality (selector, delegate method, whatever) into a class via a protocol extension. It's an appealing notion but it's just not going to work.

这篇关于使用选择器错误的Swift 3协议扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆