什么是Swift中等同于_cmd的东西?

20

我想获取当前方法名称,用于类似这个的格式化消息中

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

此外,我想使用_cmd来设置相关对象。感谢任何想法。


4
__FUNCTION__是一个Swift语言中的特殊标识符,用于返回当前函数的名称。 - Bryan Chen
1
这个问题是怎么重复的? - Yogesh Suthar
这是一个重复的问题,链接为https://dev59.com/QWAf5IYBdhLWcg3wlDmb。 - rob mayoff
2个回答

41
NSStringFromSelector(_cmd); // Objective-C

print(#function) // Swift 4, 5

2
"FUNCTION" 将被弃用并从 Swift 3 中移除,因此请改用:#function - David.Chu.ca
4
确切地说,在Swift 2.2中,像__FILE____LINE____COLUMN____FUNCTION__这样的调试标识符已被替换为#file#line#column#function - cherrmanncom
https://github.com/apple/swift-evolution/blob/master/proposals/0028-modernizing-debug-identifiers.md - i_am_jorf
这不一样。_cmd 是一个选择器类型,而 #function 不是 #selector 类型。 - eonil

1

在Swift中没有与_cmd相对应的东西。在Swift中很少有使用它的理由。

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

  • 在宏中,宏会在代码中展开,因此如果_cmd出现在宏中,则会将其插入到使用它的源代码中,因此方法名称可以在宏中使用。但是,在Swift中不存在这样的宏。此外,宏是编译时的机制,因此类似于__FUNCTION__的编译时机制将起到类似的作用。
  • 您可以定义一个接受self_cmd的C函数,并将其用作多个方法的实现,通过使用class_addMethodclass_replaceMethod添加它,函数内部的_cmd将有助于区分不同的方法调用。但是,在Swift中无法使用class_addMethodclass_replaceMethod
  • 方法交换也是一种干扰方法实现的过程。由于在交换中,您交换了两个方法的实现,_cmd将有助于显示调用中使用的实际方法名称,该名称可能与源代码中代码所在的方法不匹配,因为实现已经被交换。我想在Swift中仍然可能进行方法交换,因为method_exchangeImplementations在Swift中仍然可用。但是,在方法交换中,您交换的方法是针对与其交换的方法量身定制的,因此如果调用它,则不会存在调用哪个方法名称的歧义。
  • 在手动获取方法的IMP(实现函数)并使用不同的选择器手动调用它的情况下。在这种情况下,函数内部可以看到_cmd中的不同选择器。但是,在Swift中您无需担心这个问题,因为获取IMP的方法不可用。

混淆应该是框架错误的最后紧急解决方案。话虽如此,这里有一篇关于 NSHipster 的 Swift 运行时文章 Swift 中的混淆 - Matteo Piombo
我不太同意。排序描述符。我喜欢使用方法的访问器名称,这样如果属性的名称更改,编译器会发出警告。 - horseshoe7
除了交换方法实现(swizzling)之外,另一个原因是更干净地覆盖可选协议选择器。如果super.responds(to:_cmd)会是一个干净的改进。 - xtravar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接