2

In Objective-C one can use _cmd as key for objc_getAssociatedObject, as described in this NSHipster article. In Swift, only __FUNCTION__ serves a similar purpose to _cmd. But I am not sure whether it is safe to do so.

2 Answers2

2

The objc_getAssociatedObject() needs a unique pointer as key. In Objective-C, _cmd has the type SEL which is a pointer, and is unique according to the referenced article.

In Swift, __FUNCTION__ has the type String which is not a pointer. When passed to a function expecting a pointer, the string is converted (probably to NSString as in Swift, Strings and Memory Addresses). It is not guaranteed that this conversion yields the same pointer in each call. Here is a simple example which demonstrates the problem in a Playground:

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

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

foo()

Output:

0x00007f8173c06500
0x00007f8173e00020

As you can see, the same __FUNCTION__ is passed as two different pointers to the bar() function.

It seems that in a compiled project you'll get the same pointer for each call, but that is – as far as I know – not documented, and since it does not work in a Playground I would not rely on it.

Therefore I consider it as not safe to use __FUNCTION__ as the key for associated objects.

A safe way would be to use the address of a global property as in Is there a way to set associated objects in Swift?.

Community
  • 1
  • 1
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
1

It's fine to use that as a key, it's just a String literal. However, you should try and avoid objc_getAssociatedObject and the objective-c runtime in general when using Swift since it's not supported for all types and it goes against the idea of safety in Swift. Hopefully fingers crossed we'll see more dynamic introspection capabilities with Swift 3.

barndog
  • 6,975
  • 8
  • 53
  • 105