Ios 实现另一个@objc协议的Swift协议

Ios 实现另一个@objc协议的Swift协议,ios,swift4,Ios,Swift4,使用Swift 4,我试图编写一个定制协议,该协议提供对@objc协议的一致性 一些代码 更具体地说,我有一个自定义协议Searchable,它提供了UIKit协议UISearchBarDelegate的简单实现,只需要实现一个回调来处理搜索过滤器更改 @objc protocol Searchable: class, UISearchBarDelegate { @objc func searchFilterChanged(_: String?) } 我在协议扩展中提供委托实现: exte

使用Swift 4,我试图编写一个定制协议,该协议提供对@objc协议的一致性

一些代码 更具体地说,我有一个自定义协议
Searchable
,它提供了UIKit协议
UISearchBarDelegate
的简单实现,只需要实现一个回调来处理搜索过滤器更改

@objc protocol Searchable: class, UISearchBarDelegate {
  @objc func searchFilterChanged(_: String?)
}
我在协议扩展中提供委托实现:

extension Searchable {
  func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    searchFilterChanged(searchText)
  }
  // .. and some other delegate methods
}
最后,在另一个扩展中,我创建并安装了搜索栏(
installSearchBar
必须从混凝土视图控制器的
viewDidLoad
调用):

问题 不幸的是,当用户在搜索栏中输入文本时,不会调用
UISearchBarDelegate
的委托方法。编译器用以下消息警告我:

非-“@objc”方法“搜索栏(uu:textDidChange:)”不满足以下条件 “@objc”协议“UISearchBarDelegate”的可选要求

但是,我无法将
@objc
添加到该方法中,因为这会导致以下编译器错误:

@objc只能与类、@objc协议和类的成员一起使用 类的具体扩展

问题 所以现在我的问题是:期望的行为是否可以在Swift中实现,或者不可能在另一个协议中实现与@objc协议的一致性

注1:我知道这可以使用子类实现;我仍然在寻找流行版本


注2:我知道有
UISearchController
,这也有助于简化搜索的实现;我不能使用这个类,因为在我的实际代码中,我有一个带有其他控件的更复杂的过滤器视图——这就是为什么我使用裸的
UISearchBar

这是因为Obj-C运行时使用动态调度(动态查找/消息传递)到一致性对象,以了解它是否确认所需的方法并调用它

默认情况下,Swift协议扩展使用静态调度。从某种意义上说,当UISearchBarDelegate将符合此协议的消息传递给类时,它找不到扩展方法,因为这是协议的静态方法。因此,您的实现既不会被运行时检测到,也不会工作

这是一个非常深刻的话题。我不希望你对我的简单段落说得很清楚。然而,当Swift协议扩展是新的(试图泛化UITableViewDelegate和DataSource)时,我尝试了这种方法,但都是徒劳的。我必须研究一下原因,根据我的经验和研究,我可以告诉你们,这与依赖于动态调度和静态调度的协议扩展的Objc消息传递有关

extension Searchable where Self: UITableViewController {
  func installSearchBar() {
    let searchBar = UISearchBar()
    searchBar.delegate = self
    tableView?.tableHeaderView = searchBar
  }
}