Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the swift equivalent to _cmd?

I want to get current method name to use in a format message similar to this one

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

Also, I want to use _cmd to set associated object. I appreciate any idea.

like image 714
LongNV Avatar asked Jun 30 '14 03:06

LongNV


2 Answers

NSStringFromSelector(_cmd); // Objective-C

print(#function) // Swift 4, 5
like image 178
Huynh Inc Avatar answered Nov 15 '22 05:11

Huynh Inc


There is no Swift equivalent of _cmd. There is little reason to use it in Swift.

Consider _cmd in Objective-C. When is it useful? Most of the time, the value of _cmd would be the same as the name of the method that the code is in, so it is already known at compile time, and there is no need for a runtime value. Here are some possible cases when _cmd is useful in Objective-C:

  • In a macro. The macro is expanded in the code, so if _cmd appears in the macro, then it is inserted into the source where it is used, and so the method name can be used inside the macro. However, such macros do not exist in Swift. Plus macros are compile-time, so a compile-time mechanism like __FUNCTION__ would work similarly.
  • You can define a C function that takes self and _cmd, and use it (the same function) as the implementation of multiple methods, by adding it using class_addMethod and class_replaceMethod, and the _cmd inside the function will help distinguish between the different method calls. However, class_addMethod and class_replaceMethod are not available in Swift.
  • Method swizzling is also a process that messes with the implementation of a method. Since in swizzling you swap the implementations of two methods, _cmd will help reveal the actual method name used in the call, which may not match the method that the code is in in the source code, since implementations are swapped. I guess method swizzling may still be possible in Swift, since method_exchangeImplementations is still available in Swift. But in method swizzling, the method you swap in is tailored for the method it is swapping with, so if it is called, there is no ambiguity which method name is being called.
  • In the case where you manually get the IMP (implementing function) of a method, and manually call it with a different selector. In this case, the inside of the function can see the different selector in _cmd. However, you don't have to worry about this in Swift because the methods that get the IMP are unavailable.
like image 45
newacct Avatar answered Nov 15 '22 06:11

newacct