2016-08-24 2 views
7

Я пытаюсь создать реализацию по умолчанию в MKMapViewDelegate, используя условное расширение следующим образом:Non - метод «@ ObjC» не удовлетворяет факультативное требование протокола «@objc» с условным расширением

extension MKMapViewDelegate where Self: NSObject { 
     func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { 
      ... 
     } 

     func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { 
      ... 
     } 
    } 

Однако при компиляции кода я получаю предупреждение

Non - '@ ObjC' метод 'MAPview (_: viewFor :) не удовлетворяет дополнительное требование '@objc' протокол 'MKMapViewDelegate'

Я ожидал, что соответствие «Я» для NSObject будет означать, что предупреждение не произойдет. В дополнение к предупреждению методы делегата не вызываются, хотя экземпляр делегата является UIViewController и, следовательно, соответствует NSObject.

Я не понимаю, как «где» работает в расширениях?

+1

Возможный дубликат [Non - метод '@ ObjC' не удовлетворяет факультативное требование о '' @objc протокол] (http://stackoverflow.com/questions/39487168/non -objc-method-does-not-удовлетворить-optional-require-of-objc-protocol) –

ответ

0

NSObject больше не будет выводить @objc от Swift 4 в связи с принятием Doug Gregor's proposal: SE-0160.

Признаюсь, я не положил в то время, чтобы понять причину вашей ошибки, хотя. Я просто опубликовал этот ответ в надежде, что кто-либо другой, прочитавший ваш вопрос, увидит следующий совет.

Это плохая практика или «запах кода», чтобы обеспечить реализацию по умолчанию для протокола для всего вашего модуля. Я бы рекомендовал альтернативный подход, в котором вы создаете настраиваемый тип, такой как MapViewDelegate с некоторыми поведением по умолчанию, которые могут быть разделены между типами, которые явно соответствуют этому .

Например:

import MapKit 
protocol MapViewDelegate: MKMapViewDelegate {} 
extension MapViewDelegate where Self: NSObject { 
    func annotationView(for annotation: MKAnnotation, in mapView: MKMapView) -> MKAnnotationView? { 
     … 
    } 

    func renderer(for overlay: MKOverlay, in mapView: MKMapView) -> MKOverlayRenderer { 
     … 
    } 
} 
final class MyMapDelegate: NSObject, MapViewDelegate { 
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { 
     return annotationView(for: annotation, in: mapView) 
    } 
    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { 
     return renderer(for: overlay, in: mapView) 
    } 
} 
+0

Хотя это функциональное решение, оно фактически не отвечает на вопрос. Вопрос в том, почему соответствие NSObject не избавляет от предупреждений. –

Смежные вопросы