Что такое быстрый эквивалент _cmd?

Я хочу получить текущее имя метода для использования в сообщении формата, подобном этому

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

Кроме того, я хочу использовать _cmd для установки связанного объекта. Я ценю любую идею.

Ответы

Ответ 1

Нет эквивалента Swift _cmd. Нет смысла использовать его в Swift.

Рассмотрим _cmd в Objective-C. Когда это полезно? В большинстве случаев значение _cmd будет таким же, как имя метода, в котором находится код, поэтому он уже известен во время компиляции, и нет необходимости в значении времени выполнения. Вот некоторые возможные случаи, когда _cmd полезен в Objective-C:

  • В макросе. Макрос расширяется в коде, поэтому, если в макросе появляется _cmd, он вставляется в источник, где он используется, и поэтому имя метода можно использовать внутри макроса. Однако такие макросы не существуют в Swift. Плюсы - это время компиляции, поэтому механизм времени компиляции, такой как __FUNCTION__, будет работать аналогичным образом.
  • Вы можете определить функцию C, которая принимает self и _cmd, и использовать ее (ту же функцию), что и реализация нескольких методов, добавив ее с помощью class_addMethod и class_replaceMethod, а _cmd внутри функции поможет различать различные вызовы методов. Тем не менее, class_addMethod и class_replaceMethod недоступны в Swift.
  • Метод swizzling также является процессом, который противоречит реализации метода. Поскольку в swizzling вы меняете реализации двух методов, _cmd поможет выявить фактическое имя метода, используемое в вызове, которое может не соответствовать методу, в котором код находится в исходном коде, поскольку реализации заменены. Я думаю, что метод swizzling все еще возможен в Swift, поскольку method_exchangeImplementations по-прежнему доступен в Swift. Но в методе swizzling метод, который вы меняете, настраивается для метода, который он меняет, поэтому, если он вызывается, не существует двусмысленности, вызываемой именем метода.
  • В случае, когда вы вручную получаете функцию IMP (функция реализации) метода и вручную вызываете ее с помощью другого селектора. В этом случае внутренняя часть функции может видеть разный селектор в _cmd. Однако вам не нужно беспокоиться об этом в Swift, потому что методы, которые получают IMP, недоступны.

Ответ 2

NSStringFromSelector(_cmd); // Objective-C

print(__FUNCTION__) // Swift 2

print(#function) // Swift 3