[英]Swift protocol implementing another @objc protocol
Using Swift 4, I'm trying to write a custom protocol which provides conformance to an @objc protocol. 使用Swift 4,我试图编写一个自定义协议,该协议提供与@objc协议的一致性。
More specifically, I have a custom protocol Searchable
which provides a simple implementation of the UIKit protocol UISearchBarDelegate
, requiring to only implement a single callback for handling search filter changes. 更具体地说,我有一个自定义协议Searchable
,它提供了UIKit协议UISearchBarDelegate
的简单实现,只需要实现一个用于处理搜索过滤器更改的回调即可。
@objc protocol Searchable: class, UISearchBarDelegate {
@objc func searchFilterChanged(_: String?)
}
I provide the delegate implementation in a protocol extension: 我在协议扩展中提供了委托实现:
extension Searchable {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchFilterChanged(searchText)
}
// .. and some other delegate methods
}
Finally, in another extension I create and install the search bar ( installSearchBar
has to be called from viewDidLoad
of the concrete view controller): 最后,在另一个扩展中,我创建并安装搜索栏(必须从具体视图控制器的viewDidLoad
调用installSearchBar
):
extension Searchable where Self: UITableViewController {
func installSearchBar() {
let searchBar = UISearchBar()
searchBar.delegate = self
tableView?.tableHeaderView = searchBar
}
}
Unfortunately, the delegate methods of UISearchBarDelegate
are not called when the user enters text in the search bar. 不幸的是,当用户在搜索栏中输入文本时,不会调用UISearchBarDelegate
的委托方法。 The compiler warns me with this message: 编译器通过以下消息警告我:
Non-'@objc' method 'searchBar(_:textDidChange:)' does not satisfy optional requirement of '@objc' protocol 'UISearchBarDelegate' 非'@objc'方法'searchBar(_:textDidChange :)'不满足'@objc'协议'UISearchBarDelegate'的可选要求
However, I cannot add @objc
to the method because this causes the following compiler error: 但是,我无法将@objc
添加到该方法,因为这会导致以下编译器错误:
@objc can only be used with members of classes, @objc protocols, and concrete extensions of classes @objc只能与类的成员,@ objc协议和类的具体扩展一起使用
So now my question is: can the desired behavior be implemented in Swift at all, or is it not possible to implement conformance to an @objc protocol in another protocol? 所以现在我的问题是:所需的行为是否可以在Swift中实现,还是不能在另一协议中实现对@objc协议的一致性?
Note 1: I know that this can be implemented using subclass; 注意1:我知道可以使用子类来实现; still I'm looking for a POP version. 我仍然在寻找POP版本。
Note 2: I know there is UISearchController
which also helps to simplify implementing search; 注2:我知道有UISearchController
,它也有助于简化实现搜索; I cannot use this class because in my actual code, I have a more complex filter view with other controls -- that's why I use a bare UISearchBar
. 我不能使用此类,因为在我的实际代码中,我具有与其他控件一起使用的更复杂的过滤器视图-这就是为什么我使用裸UISearchBar
的原因。
This is due to the fact that Obj-C runtime uses Dynamic dispatch (dynamic lookup/message passing) to conforming object to know if it confirms the required method and invoke it. 这是因为,Obj-C运行时使用动态调度(动态查找/消息传递)对符合条件的对象进行了解,以了解其是否确认了所需的方法并调用了它。
Swift protocol extension by default use static dispatch. Swift协议扩展默认情况下使用静态调度。 In a sense, when UISearchBarDelegate passes a message to your class that conforms to this protocol it can't find the extension method as this is static to the protocol. 从某种意义上说,当UISearchBarDelegate向符合此协议的类传递消息时,由于该协议是静态的,因此找不到扩展方法。 And hence your implementation is neither detected by the runtime nor does it work. 因此,运行时既无法检测到您的实现,也无法正常工作。
This is a very deep topic. 这是一个非常深刻的话题。 I don't expect you to be clear with my simple paragraph. 我不希望您用我的简单段落弄清楚。 However, I tried this when Swift Protocol Extension was new (trying to generalize UITableViewDelegate and DataSource) but all in vain. 但是,当Swift协议扩展是新的(试图推广UITableViewDelegate和DataSource)时,我尝试了此操作,但是全部徒劳。 I had to research into why and I can tell you from my experience and research this has to do with Objc messaging passing relying on dynamic dispatch and protocol extension being statically dispatched. 我必须研究原因,并可以从我的经验中告诉您,这与Objc消息传递有关,后者依赖于动态调度和静态协议扩展。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.