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

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

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

但是,当我编译代码时,我得到警告



我希望对“Self”与NSObject的一致性将意味着不会发生该警告。最重要的是,即使委托(delegate)实例是UIViewController并因此符合NSObject,也不会调用委托(delegate)方法。

我是否误解了扩展中的“where”如何工作?

最佳答案

自Swift 4起,由于接受Doug Gregor's proposal: NSObject .,因此@objc将不再推断SE-0160
我承认我虽然没有花时间去理解您的错误背后的原因。我只是发布了此答案,希望其他阅读您的问题的人会看到以下建议。

为整个模块的协议(protocol)提供默认实现是一种不好的做法或“代码异味”。我建议一种替代方法,其中您创建具有某些默认行为的自定义类型(例如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)
    }
}

关于swift - 非-'@objc'方法不满足带有条件扩展的 '@objc'协议(protocol)的可选要求,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39118030/

10-15 09:37