【问题标题】:What is the swift equivalent to _cmd?_cmd 的 swift 等价物是什么?
【发布时间】:2014-06-30 03:44:21
【问题描述】:

我想获取当前方法名称以在与此类似的格式消息中使用

[NSExeception raise:NSInternalInconsistencyException format:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]

另外,我想使用 _cmd 来设置关联对象。我很感激任何想法。

【问题讨论】:

标签: ios objective-c swift selector


【解决方案1】:
NSStringFromSelector(_cmd); // Objective-C

print(#function) // Swift 4, 5

【讨论】:

  • "FUNCTION" 将被弃用并将从 Swift 3 中删除,因此,请改用:#function
  • 准确的调试标识符如__FILE____LINE____COLUMN____FUNCTION__在斯威夫特 2.2.
  • 这不一样。 _cmd 是选择器类型,#function 不是 #selector 类型。
【解决方案2】:

没有与_cmd 等效的Swift。没有什么理由在 Swift 中使用它。

考虑一下 Objective-C 中的_cmd。什么时候有用?大多数情况下,_cmd 的值与代码所在方法的名称相同,因此在编译时就已经知道,不需要运行时值。以下是 _cmd 在 Objective-C 中有用的一些可能情况:

  • 在宏中。宏在代码中展开,所以如果_cmd出现在宏中,那么它会被插入到使用它的源代码中,这样方法名就可以在宏内部使用。然而,这样的宏在 Swift 中并不存在。 Plus 宏是编译时的,所以像 __FUNCTION__ 这样的编译时机制也可以类似地工作。
  • 您可以定义一个接受self_cmd 的C 函数,并使用它(同一个函数)作为多个方法的实现,通过使用class_addMethodclass_replaceMethod 和@987654332 添加它函数内部的@将有助于区分不同的方法调用。但是,class_addMethodclass_replaceMethod 在 Swift 中不可用。
  • 方法调配也是一个与方法实现混淆的过程。由于在 swizzling 中您交换了两个方法的实现,_cmd 将有助于显示调用中使用的实际方法名称,这可能与源代码中代码所在的方法不匹配,因为实现是交换的。我猜在 Swift 中方法 swizzling 仍然是可能的,因为 method_exchangeImplementations 在 Swift 中仍然可用。但是在方法调配中,你交换的方法是为它交换的方法量身定制的,所以如果它被调用,那么调用哪个方法名称就没有歧义了。
  • 在手动获取方法的IMP(实现函数),并使用不同的选择器手动调用它的情况下。在这种情况下,函数内部可以看到_cmd中的不同选择器。但是,在 Swift 中您不必担心这一点,因为获取 IMP 的方法不可用。

【讨论】:

  • Swizzling 应该是解决框架错误的最后一个紧急解决方案。话虽如此,这是 NSHipster swizzling in Swift 的一篇关于 Swift 运行时的帖子
  • 我不同意。排序描述符。我喜欢使用方法的访问器名称,这样如果属性名称发生变化,编译器就会报错。
  • 除了 swizzling 之外,一个原因是更干净地覆盖可选的协议选择器。如果 super.responds(to:_cmd) 将是一个干净的改进。
猜你喜欢
  • 2014-08-12
  • 2014-08-01
  • 1970-01-01
  • 2014-09-24
  • 2016-12-13
  • 2014-07-31
  • 1970-01-01
相关资源
最近更新 更多