2016-08-24 11 views
7

Próbuję utworzyć domyślną implementację danego MKMapViewDelegate za pomocą rozszerzenia warunkową następująco:Non - metoda „@ objc” nie spełnia wymogu dodatkowego protokołu „@objc” z rozszerzeniem warunkowego

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

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

jednak kiedy skompilować kod otrzymuję ostrzeżenie

Non - '@ objc' metoda 'MapView (_: viewFor :)' nie spełnia wymogu dodatkowego protokołu '@objc' 'MKMapViewDelegate'

Spodziewałem się, że zgodność z "Własnością" w NSObject oznaczałaby, że ostrzeżenie nie wystąpiłoby. Na górze ostrzeżenia metody delegatów nie są wywoływane, mimo że instancja delegata jest kontrolerem UIViewController i dlatego jest zgodna z NSObject.

Czy nie rozumiem, jak "gdzie" działa w rozszerzeniach?

+1

Możliwe duplikat [Non - metoda '@ objc' nie spełniają wymogu dodatkowego protokołu '@objc'] (http://stackoverflow.com/questions/39487168/non -objc-method-does-not-satisfy-optional-requirement-of-objc-protokół) –

Odpowiedz

0

NSObject nie będzie już wywnioskować @objc jak Swift 4 w związku z przyjęciem Doug Gregor's proposal: SE-0160.

muszę przyznać, że nie umieścić w czasie, aby zrozumieć powód swojej błędu chociaż. Po prostu wysłałem tę odpowiedź w nadziei, że ktokolwiek czytający twoje pytanie zobaczy następującą radę.

To jest zła praktyka lub "zapach kodu", aby zapewnić domyślną implementację protokołu dla całego modułu. Polecam alternatywne podejście polegające na utworzeniu niestandardowego typu, takiego jak MapViewDelegate z pewnym domyślnym zachowaniem, które może być współużytkowane przez typy, które jawnie są zgodne z tymi .

Na przykład:

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

Chociaż jest to rozwiązanie funkcjonalne, to w rzeczywistości nie odpowiada na pytanie. Pytanie brzmiało, dlaczego zgodność z NSObject nie eliminuje ostrzeżeń. –

Powiązane problemy