Objective c @Swift 3的objc要求?
你知道我为什么要使用我的Swift 3 iOS应用程序吗Objective c @Swift 3的objc要求?,objective-c,swift,swift3,mkmapview,Objective C,Swift,Swift3,Mkmapview,你知道我为什么要使用我的Swift 3 iOS应用程序吗 @objc(mapView:rendererForOverlay:) func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { 触发器, 但是如果我用这个来代替上面的陈述 func mapView(mapView: MKMapView, rendererFor overlay: MKOverlay) ->
@objc(mapView:rendererForOverlay:) func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
触发器,
但是如果我用这个来代替上面的陈述
func mapView(mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
不会触发。一个明显的问题是,在Swift 3中,这不是正确的签名:
func mapView(mapView: MKMapView,
rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
最重要的是:
请注意区别(“下划线”)
如果代码不在显式声明与MKMapViewDelegate一致性的类或扩展声明中,则可能会出现另一个问题。斯威夫特3在这方面非常挑剔。(您没有提供足够的上下文,我无法知道您是否正确理解了该部分。)
@objc
声明通过显式地将此函数桥接到Objective-C来解决这两个问题。但是如果您在这两个方面都做得正确,Swift将为您完成桥接,并且不需要使用@objc
。一个明显的问题是,在Swift 3中,这不是正确的签名:
func mapView(mapView: MKMapView,
rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
最重要的是:
请注意区别(“下划线”)
如果代码不在显式声明与MKMapViewDelegate一致性的类或扩展声明中,则可能会出现另一个问题。斯威夫特3在这方面非常挑剔。(您没有提供足够的上下文,我无法知道您是否正确理解了该部分。)
@objc
声明通过显式地将此函数连接到Objective-C来解决这两个问题。但是,如果您在这两个方面都做得正确,Swift将为您完成连接,而@objc
将不再需要。即使matt的回答是正确的,我想解释下划线的原因
为什么需要下划线
简短回答:因为这是方法的声明:
optional func mapView(_ mapView: MKMapView,
rendererFor overlay: MKOverlay) -> MKOverlayRenderer
长答覆:
tl;dr:您需要它来删除Swift 3.0中第一个参数的前导参数名称
要理解你必须了解整个故事:
Objective-C类似于命名参数:整个方法声明(包括参数声明前面的部分)是方法标识符的一部分。有方法…:
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView
rendererForOverlay:(id<MKOverlay>)overlay;
-(mkoverlayrender*)地图视图:(MKMapView*)地图视图
RenderForOverlay:(id)覆盖;
…这意味着方法(选择器)的标识符是mapView:renderForOverlay:
。该系统简单,使用时间长。它很强大,因为它不需要方法重载
根据斯威夫特的设计原则,为了使工作和简单的事情变得复杂,无论它们是否工作,他们做了一些巧妙的破解:
Swift具有类似于从Objective-C选择器到Swift函数和参数标识符的转换机制。他们在Swift 1.2(?)中找到了一个很好的解决方案,使事情变得更容易。后来他们认识到,伟大而简单的解决方案令人困惑,他们在Swift 2.0中提供了一个新的解决方案,该解决方案更强大、更简单。后来,他们认识到,更大、更简单的解决方案令人困惑,他们在Swift 3.0中提供了一个新的解决方案,这个解决方案比目前更大
在Swift<3.0中,第一个(外部)参数名默认为nothing(因为选择器的第一部分成为函数名),此规则不再适用,您必须指定它。下划线只是表示没有外部名称。因此,您的方法名称被正确地转换为Objective-C的选择器
它采用函数名mapView
,因为\uu
,所以没有添加外部名称,因此它是mapView:
。然后它添加下一个外部参数名renderFor
,这将导致mapView:renderFor
,然后参数名overlay
,将其大写为overlay
,这将导致mapView:renderForOverlay:
——正确的选择器
很简单,很简单。另一个使Swift中的事情变得非常简单的功能。与Objective-C中一样容易,即使matt的答案是正确的,我也要解释下划线的原因 为什么需要下划线 简短回答:因为这是方法的声明:
optional func mapView(_ mapView: MKMapView,
rendererFor overlay: MKOverlay) -> MKOverlayRenderer
长答覆:
tl;dr:您需要它来删除Swift 3.0中第一个参数的前导参数名称
要理解你必须了解整个故事:
Objective-C类似于命名参数:整个方法声明(包括参数声明前面的部分)是方法标识符的一部分。有方法…:
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView
rendererForOverlay:(id<MKOverlay>)overlay;
-(mkoverlayrender*)地图视图:(MKMapView*)地图视图
RenderForOverlay:(id)覆盖;
…这意味着方法(选择器)的标识符是mapView:renderForOverlay:
。该系统简单,使用时间长。它很强大,因为它不需要方法重载
根据斯威夫特的设计原则,为了使工作和简单的事情变得复杂,无论它们是否工作,他们做了一些巧妙的破解:
Swift具有类似于从Objective-C选择器到Swift函数和参数标识符的转换机制。他们在Swift 1.2(?)中找到了一个很好的解决方案,使事情变得更容易。后来他们认识到,伟大而简单的解决方案令人困惑,他们在Swift 2.0中提供了一个新的解决方案,该解决方案更强大、更简单。后来,他们认识到,更大、更简单的解决方案令人困惑,他们在Swift 3.0中提供了一个新的解决方案,这个解决方案比目前更大
在Swift<3.0中,第一个(外部)参数名默认为nothing(因为选择器的第一部分成为函数名),此规则不再适用,您必须指定它。下划线只是表示没有外部名称。因此,您的方法名称被正确地转换为Objective-C的选择器
它采用函数名mapView
由于