在协议扩展中添加目标操作失败

Ram*_*lya 11 ios swift protocol-extension

我有一组视图控制器,它们有一个菜单栏按钮.我为那些viewControllers创建了一个协议来采用.此外,我已经扩展了协议以添加默认功能.

我的协议看起来像,

protocol CenterViewControllerProtocol: class {

    var containerDelegate: ContainerViewControllerProtocol? { get set }

    func setupMenuBarButton()
}
Run Code Online (Sandbox Code Playgroud)

并且,扩展看起来像这样,

extension CenterViewControllerProtocol where Self: UIViewController {

    func setupMenuBarButton() {
        let barButton = UIBarButtonItem(title: "Menu", style: .Done, target: self, action: "menuTapped")
        navigationItem.leftBarButtonItem = barButton
    }

    func menuTapped() {
        containerDelegate?.toggleSideMenu()
    }
}
Run Code Online (Sandbox Code Playgroud)

我的viewController采用协议 -

class MapViewController: UIViewController, CenterViewControllerProtocol {

    weak var containerDelegate: ContainerViewControllerProtocol?

    override func viewDidLoad() {
        super.viewDidLoad()

        setupMenuBarButton()
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到了很好的显示按钮,但是当我点击它时,应用程序崩溃了

[AppName.MapViewController menuTapped]: unrecognized selector sent to instance 0x7fb8fb6ae650
Run Code Online (Sandbox Code Playgroud)

如果我在ViewController中实现该方法,它可以正常工作.但我要复制符合协议的所有viewControllers中的代码.

我在这里做错了什么?提前致谢.

小智 0

目前似乎不支持使用协议扩展。根据fluidsonic在这里的回答:

在任何情况下,您打算通过选择器使用的所有函数都应标有dynamic或@objc。如果这导致 @objc 无法在此上下文中使用的错误,那么您尝试执行的操作根本不受支持。”

在您的示例中,我认为解决此问题的一种方法是创建 UIBarButtonItem 的子类,每当点击它时都会调用一个块。然后你可以containerDelegate?.toggleSideMenu()在该块内调用。