【问题标题】:_cmd in Swift for selector useSwift 中的 _cmd 供选择器使用
【发布时间】:2016-12-09 05:08:27
【问题描述】:

我正在尝试在 Swift 3 中编写以下 ObjC 代码:

- (void)scrollViewScroll:(UIScrollView*)scrollView {
    // some code
    if ([_userDelegate respondsToSelector:_cmd]) {
        [_userDelegate scrollViewDidEndDecelerating:scrollView];
    }
}

但不知道用什么替换 _cmd。我正在尝试功能,但它不起作用:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    // some code
    if (userDelegate?.responds(to: #function))! {
        userDelegate?.scrollViewDidScroll!(scrollView)
    }
}

使用#selector(scrollViewDidScroll(_:)) 有效,但有没有办法让它保持通用?

编辑:可能重复的答案是关于获取函数名称,这不是我上面要问的

【问题讨论】:

  • @i_am_jorf 我已经看到了那个答案,但是如您所见,使用#function 不起作用..
  • 该问题的接受答案比投票率最高的答案更适合您。
  • @jtbandes 嗨,是的,谢谢,我有点明白了,但仍然怀疑在经过两年的快速进化之后是否没有办法做到这一点,因为这个问题并没有问同样的问题事情决定问这个
  • 不,没有办法。这是最近讨论过的:mail-archive.com/swift-evolution@swift.org/msg18521.html

标签: objective-c swift macros selector


【解决方案1】:

Swift 没有选择器。 Objective-C 在 Swift 调用函数时向对象发送消息。所以检查对象是否可以响应选择器是 Objective-C 和 NSObject 的一部分。

Swift 协议函数默认为required。 Swift 编译器不允许你跳过那些函数实现。但是你可以让他们optional,并且你必须在调用之前检查这些函数是否实现。

在这种情况下,只需调用末尾带有问号的函数,就像这样

if let returnValue = userDelegate?.theOptionalFunction?(arguments) {
    // you got value
} else {
    // delegate returned nil or delegate function isn't implemented
}

来源:The Swift Programming Language

可以使用可选链接调用可选协议要求,以说明该要求未由符合协议的类型实现的可能性。您可以通过在调用方法名称后写一个问号来检查可选方法的实现,例如 someOptionalMethod?(someArgument)。

【讨论】:

  • 虽然不是严格意义上的正确——因为 Swift 可以并且必须参与 Objective-C 方法调度机制,例如使用 UIKit (因此有#selector),答案帮助我意识到如果我使用可选链接,我根本不需要包装ifuserDelegate?.scrollViewDidScroll?(scrollView)。它解决了我的问题,但我想不会解决其他用例.. 感谢您的回答!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多