[英]Swift protocol implementing another @objc protocol
使用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
}
最后,在另一個擴展中,我創建並安裝搜索欄(必須從具體視圖控制器的viewDidLoad
調用installSearchBar
):
extension Searchable where Self: UITableViewController {
func installSearchBar() {
let searchBar = UISearchBar()
searchBar.delegate = self
tableView?.tableHeaderView = searchBar
}
}
不幸的是,當用戶在搜索欄中輸入文本時,不會調用UISearchBarDelegate
的委托方法。 編譯器通過以下消息警告我:
非'@objc'方法'searchBar(_:textDidChange :)'不滿足'@objc'協議'UISearchBarDelegate'的可選要求
但是,我無法將@objc
添加到該方法,因為這會導致以下編譯器錯誤:
@objc只能與類的成員,@ objc協議和類的具體擴展一起使用
所以現在我的問題是:所需的行為是否可以在Swift中實現,還是不能在另一協議中實現對@objc協議的一致性?
注意1:我知道可以使用子類來實現; 我仍然在尋找POP版本。
注2:我知道有UISearchController
,它也有助於簡化實現搜索; 我不能使用此類,因為在我的實際代碼中,我具有與其他控件一起使用的更復雜的過濾器視圖-這就是為什么我使用裸UISearchBar
的原因。
這是因為,Obj-C運行時使用動態調度(動態查找/消息傳遞)對符合條件的對象進行了解,以了解其是否確認了所需的方法並調用了它。
Swift協議擴展默認情況下使用靜態調度。 從某種意義上說,當UISearchBarDelegate向符合此協議的類傳遞消息時,由於該協議是靜態的,因此找不到擴展方法。 因此,運行時既無法檢測到您的實現,也無法正常工作。
這是一個非常深刻的話題。 我不希望您用我的簡單段落弄清楚。 但是,當Swift協議擴展是新的(試圖推廣UITableViewDelegate和DataSource)時,我嘗試了此操作,但是全部徒勞。 我必須研究原因,並可以從我的經驗中告訴您,這與Objc消息傳遞有關,后者依賴於動態調度和靜態協議擴展。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.