非 - ' @ objc'方法不满足' @ objc'带条件扩展的协议

时间:2016-08-24 08:20:48

标签: swift swift-extensions

我尝试使用条件扩展创建MKMapViewDelegate的默认实现,如下所示:

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'的选择要求protocol' MKMapViewDelegate'

我期望在“自我”中表现出一致性。对NSObject意味着不会发出警告。除了警告之外,即使委托实例是UIViewController并且因此符合NSObject,也不会调用委托方法。

我是否误解了'哪里'在扩展中工作?

1 个答案:

答案 0 :(得分:0)

由于接受Doug Gregor's proposal: SE-0160.

NSObject将不再推断Swift 4的@objc

我承认我没有花时间去了解你的错误背后的原因。我只是发布了这个答案,希望其他人阅读你的问题会看到以下建议。

为整个模块提供协议的默认实现,这是一种不好的做法,或“代码味道”。我建议使用另一种方法,其中您创建一个自定义类型,例如MapViewDelegate,其默认行为可以在明确符合protocol的类型之间共享。

例如:

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)
    }
}