2016-08-24 4 views
7

私は次のように条件付きの拡張子を使用してMKMapViewDelegateのデフォルトの実装を作成しようとしています:非 - 「@にObjC」メソッドは、条件付きの拡張子を持つ「@objc」プロトコルのオプションの要件を満たしていない

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

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

しかし、私は私が手コード警告

非コンパイルするとき - '@にObjC' メソッド 'のMapView(_:viewForは:)' '@objc' プロトコル 'MKMapViewDelegate'

のオプションの要件を満たしていません

「Self」のNSObjectへの適合が、警告が発生しないことを意味することを期待しました。警告の上に、デリゲートインスタンスがUIViewControllerであり、したがってNSObjectに準拠していても、デリゲートメソッドは呼び出されません。

エクステンションで「どこ」がどのように機能するのか誤解していますか?

+1

可能重複[非 - '@にObjC' メソッドは、 '@objc' プロトコルの任意の要件を満たさない(http://stackoverflow.com/questions/39487168/non -objc-method-does-not-satisfied-optional-of-objc-protocol) –

答えて

0

NSObjectは、もはや私は私もあなたのエラーの背後にある理由を理解するために時間に入れていない認めるによるDoug Gregor's proposal: SE-0160.

の受け入れにスウィフト4のよう@objcを推測しません。私はあなたの質問を読んでいる誰かが次のアドバイスを見ることを期待してこの回答を投稿しただけです。

モジュール全体のプロトコルにデフォルト実装を提供することは悪いことですが、「コードの匂い」です。別の方法として、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への適合が警告を取り除かないのかということでした。 –

関連する問題