Swift: печать имени функции, хранящейся в переменной - PullRequest
0 голосов
/ 29 августа 2018

Следующий пример:

let plus: (Int, Int) -> Int = (+)
print(plus)
debugPrint(plus)

print(UIView.removeFromSuperview)
debugPrint(UIView.removeFromSuperview)

print(UnsafePointer<Int>.distance(to:))
debugPrint(UnsafePointer<Int>.distance(to:))

Печатает бесполезный вывод:

(функция)
(Функция)
(Функция)
(Функция)
(Функция)
(Функция)

Есть ли способ получить имя функции в Swift? Я имею в виду, а не имя функции, которая работает в данный момент (#funciton). Но имя функции, хранящейся в переменной, или функция класса и т. Д. Каждый язык, особенно тот, который претендует на то, чтобы быть функциональным, должен иметь такую ​​способность, верно?

Ответы [ 2 ]

0 голосов
/ 30 августа 2018

Swift - статически настроенный язык программирования. Это приводит к тому, что Swift максимально использует адреса памяти, когда требуется вызвать функцию. Побочным эффектом является невозможность захвата имени вызываемой функции, поскольку в большинстве случаев это будет простой адрес памяти.

#function работает, потому что эта конструкция заменяется в время компиляции функцией вызова (это не конструкция времени выполнения).

Если у вас есть доступные символы отладки, вы можете восстановить имя функции по двоичному адресу, однако для этого потребуется доступ к инфраструктуре dSYM из вашего приложения, что маловероятно, что вы захотите сделать, так как вы отправляете app вместе с символами отладки - это приглашение для хакеров провести обратный инжиниринг в вашем приложении.

Динамически отправляемые языки, такие как Objective-C, сохраняют ссылку на вызываемую функцию (селектор), но только в том случае, если вызываемая функция является методом (то есть функцией-членом). Другие языки, такие как Ruby, JavaScript, являются интерпретируемыми языками, что делает имя функции доступным в любое время.

0 голосов
/ 29 августа 2018

По состоянию на Swift 3 .dynmaicType устарела, и теперь вы будете использовать type(of: )

let plus: (Int, Int) -> Int = (+)
print(type(of: plus))
debugPrint(type(of: plus))
print(type(of: UIView.removeFromSuperview))
debugPrint(type(of: UIView.removeFromSuperview))

print(type(of: UnsafePointer<Int>.distance(to:)))
debugPrint(type(of: UnsafePointer<Int>.distance(to:)))

В результате получается следующий вывод.

(Int, Int) -> Int

(Swift.Int, Swift.Int) -> Swift.Int

(UIView) -> () -> ()

(__ ObjC.UIView) -> () -> ()

(UnsafePointer) -> (UnsafePointer) -> Int

(Swift.UnsafePointer) -> (Swift.UnsafePointer) -> Swift.Int

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...