簡體   English   中英

Swift協議實現另一個@objc協議

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM