简体   繁体   English

来自Objective-C协议的Swift扩展

[英]Swift Extensions from Objective-C Protocol

So I am using an Objective-C library that makes use of MKMapView . 所以我正在使用利用MKMapView的Objective-C库。 So there is a class: 所以有一个类:

 @interface BSWeatherMapView : MKMapView
    /** The receiver’s delegate. */
    @property (nonatomic, weak) id<BSWeatherMapViewDelegate> delegate; 

Its protocol is defined with this method: 使用以下方法定义其协议:

    @protocol BSWeatherMapViewDelegate<MKMapViewDelegate>
    @optional 
    - (MKAnnotationView *)mapView:(BSWeatherMapView *)mapView viewForAnnotation:(id<MKAnnotation >)annotation;

My swift class has an extension doing the following: 我的swift课程有一个扩展程序,可以执行以下操作:

extension ViewController : BSWeatherMapViewDelegate {
func mapView(mapView: BSWeatherMapView!, viewForAnnotation annotation: AnyObject) -> MKAnnotationView! {}
}

When I do this I get the following error: Objective-C method mapView:viewForAnnotation: provided by method mapView(_:viewForAnnotation:) conflicts with optional requirement method mapView(_:viewForAnnotation:) in protocol MKMapViewDelegate 当我这样做时,出现以下错误:Objective-C方法mapView:viewForAnnotation:由方法mapView(_:viewForAnnotation:)提供,与协议MKMapViewDelegate可选需求方法mapView(_:viewForAnnotation:)冲突

I have no clue how to get past this... anyone? 我不知道该如何克服...任何人?

Thanks, 谢谢,

The problem is that this Objective-C declaration is illegal: 问题在于此Objective-C声明是非法的:

@protocol BSWeatherMapViewDelegate<MKMapViewDelegate>
@optional 
- (MKAnnotationView *)mapView:(BSWeatherMapView *)mapView viewForAnnotation:(id<MKAnnotation >)annotation;
@end

The illegality is that MKMapViewDelegate already declares a method called mapView:viewForAnnotation: , but with a different first parameter type. 非法之处在于MKMapViewDelegate已经声明了一个名为mapView:viewForAnnotation:的方法,但具有不同的第一个参数类型。 There is no overloading in Objective-C, so it is impossible to distinguish between the MKMapViewDelegate mapView:viewForAnnotation: and the BSWeatherMapViewDelegate mapView:viewForAnnotation: . Objective-C中没有重载,因此无法区分MKMapViewDelegate mapView:viewForAnnotation:和BSWeatherMapViewDelegate mapView:viewForAnnotation: :。 If the same app were to try to implement both, the runtime would have no way of knowing which is which. 如果同一个应用尝试同时实现这两个应用,则运行时将无法知道哪个是哪个。

The Objective-C compiler doesn't actually stop you as long as you don't try to implement both methods; 只要您不尝试实现这两种方法,Objective-C编译器就不会真正阻止您。 it warns but it does not error . 发出警告,但不会出错 (You, while writing your app in Objective-C, have presumably been blithely ignoring the warning; but that was a mistake, as it would have clued you in to the fact that you were already in trouble.) If you had tried to implement both, you would have gotten a "duplicate declaration" compile error. (你,而在Objective-C编写的应用程序,都可能被轻率地忽略了警告,但是这是一个错误,因为它会避让你到你麻烦已经事实。)如果你试图实施两者都将导致“重复声明”编译错误。

But the Swift compiler, which can tell the difference between them because it does permit overloading, is more proactive and stops you from implementing either of them. 但是Swift编译器可以主动告诉他们之间的区别,因为它确实允许重载,它更加主动,可以阻止您实现其中任何一个。 Thus, you can never implement either of them on the Swift side. 因此,您永远不能在Swift端实现它们中的任何一个。

Your choices, therefore, are: 因此,您的选择是:

  • Abandon use of this library, as it is faulty. 放弃使用此库,因为它有问题。

  • Fix the library to be legal (assuming you have access to the source). 将库修复为合法(假设您有权访问源)。 For example, change the name of the BSWeatherMapViewDelegate method wherever it occurs. 例如,更改BSWeatherMapViewDelegate方法的名称,无论它在哪里发生。

  • Implement these delegate methods only in Objective-C, not in Swift. 仅在Objective-C中实现这些委托方法,而不在Swift中实现。

Unfortunately I could not alter the library nor could I move to a differnent one for the time being. 不幸的是,我暂时无法更改该库,也无法移至其他库。 What I ended up doing was I created an Objective-C class that was the delegate for BSWeatherMapViewDelegate. 我最终要做的是创建了一个Objective-C类,该类是BSWeatherMapViewDelegate的委托。 I then created similar methods that each of the delegate methods called. 然后,我创建了每个委托方法都调用的类似方法。 Finally, in swift, I subclassed this intermediate Obj-C class and overrode the intermediate methods. 最后,我迅速将这个中间Obj-C类子类化,并覆盖了中间方法。 Not an ideal solution but it got the job done. 这不是理想的解决方案,但可以完成工作。 Thank you for all of your suggestions. 感谢您的所有建议。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM