2015-11-19 3 views

ответ

2

objc_getAssociatedObject() нужен уникальный указатель в качестве ключа. В Objective-C _cmd имеет тип SEL, который является указателем и является уникальным в соответствии с указанной статьей.

В Swift, __FUNCTION__ имеет тип String, который не является указателем. При переходе к функции, ожидающей указателя, строка преобразована (возможно, в NSString как в Swift, Strings and Memory Addresses). Не гарантируется, что это преобразование дает один и тот же указатель в каждом вызове. Вот простой пример, который демонстрирует проблему в Playground:

func bar(ptr : UnsafePointer<Void>) { 
    print(ptr) 
} 

func foo() { 
    bar(__FUNCTION__) 
    bar(__FUNCTION__) 
} 

foo() 

Выход:

0x00007f8173c06500 
0x00007f8173e00020 

Как вы можете видеть, тот же __FUNCTION__ передается как два разных указателей на функции bar().

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

Поэтому я считаю это не безопасно использовать __FUNCTION__ как ключ для связанных с ними объектов.

Безопасным способом было бы использовать адрес глобальной собственности , как в Is there a way to set associated objects in Swift?.

1

Это нормально использовать в качестве ключа, это всего лишь буква String. Тем не менее, вы должны стараться избегать objc_getAssociatedObject и время выполнения объекта-c в целом при использовании Swift, поскольку оно не поддерживается для всех типов, и это противоречит идее безопасности в Swift. Надеюсь пальцы скрещены мы увидим более динамические возможности интроспекции с Swift 3.

Смежные вопросы