因此,我正在使用一个利用 MKMapView
的 Objective-C 库。
所以有一个类:
@interface BSWeatherMapView : MKMapView
/** The receiver’s delegate. */
@property (nonatomic, weak) id<BSWeatherMapViewDelegate> delegate;
它的协议(protocol)是用这个方法定义的:
@protocol BSWeatherMapViewDelegate<MKMapViewDelegate>
@optional
- (MKAnnotationView *)mapView:(BSWeatherMapView *)mapView viewForAnnotation:(id<MKAnnotation >)annotation;
我的 swift 类有一个扩展,可以执行以下操作:
extension ViewController : BSWeatherMapViewDelegate {
func mapView(mapView: BSWeatherMapView!, viewForAnnotation annotation: AnyObject) -> MKAnnotationView! {}
}
当我这样做时,出现以下错误:
方法 mapView(_:viewForAnnotation:)
提供的 Objective-C 方法 mapView:viewForAnnotation:
与可选要求方法 mapView(_:viewForAnnotation:)
冲突> 在协议(protocol) MKMapViewDelegate
我不知道如何克服这个……有人吗?
谢谢,
最佳答案
问题是这个 Objective-C 声明是非法的:
@protocol BSWeatherMapViewDelegate<MKMapViewDelegate>
@optional
- (MKAnnotationView *)mapView:(BSWeatherMapView *)mapView viewForAnnotation:(id<MKAnnotation >)annotation;
@end
非法之处在于 MKMapViewDelegate 已经声明了一个名为 mapView:viewForAnnotation:
的方法,但第一个参数类型不同。 Objective-C 中没有重载,因此无法区分 MKMapViewDelegate mapView:viewForAnnotation:
和 BSWeatherMapViewDelegate mapView:viewForAnnotation:
。如果同一个应用试图同时实现两者,运行时将无法知道哪个是哪个。
只要您不尝试实现这两种方法,Objective-C 编译器实际上并不会阻止您;它警告但它不会错误。 (您在使用 Objective-C 编写您的应用程序时,大概一直在轻率地忽略警告;但这是一个错误,因为它会让您意识到您已经遇到麻烦的事实。)如果您 尝试同时实现两者,您会得到“重复声明”编译错误。
但是 Swift 编译器可以分辨出它们之间的区别,因为它确实允许重载,它更主动并且阻止你实现任一个 其中。因此,您永远不能在 Swift 端实现它们中的任何一个。
因此,您的选择是:
放弃使用这个库,因为它有问题。
修复库使其合法(假设您可以访问源代码)。例如,更改 BSWeatherMapViewDelegate 方法的名称。
仅在 Objective-C 中实现这些委托(delegate)方法,而不是在 Swift 中。
关于objective-c - 来自 Objective-C 协议(protocol)的 Swift 扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37759117/