4

I've been using objc_setAssociatedObject() this way:

objc_setAssociatedObject(myObject, @"myKey1", obj2, OBJC_ASSOCIATION_ASSIGN);

In particular, my key is a character string, so the compiler uses the pointer to that string. I specify the same character string in objc_getAssociatedObject():

objc_getAssociatedObject(myObject, @"myKey1").

I've been using this scheme for a long time without any problem. However, the examples on SO use a pointer to a static variable, so I now realize that my method might be incorrect. The compiler uses the same pointer each time, so it's always worked.

Is my method okay? It seems equivalent to using a pointer to a static string. Under what circumstances might the compiler store two different copies of my key?

Jeff
  • 2,659
  • 1
  • 22
  • 41
  • this might help http://stackoverflow.com/questions/1937685/static-nsstring-usage-vs-inline-nsstring-constants – Flexicoder Apr 07 '15 at 08:56

3 Answers3

1

Actually two equal string constants have the same address, if they are used in the same translation unit. (A TU is a term from C, basically it means: "The same .m file".) But this behavior is not guaranted and might change in future.

This caveat applies to compile-time string literals as well. Historically, string literals (using the @"..." syntax) have been uniqued across translation units during linking. This is an implementation detail of the compiler and should not be relied upon. If you are using such code, please use global string constants instead (NSString * const MyConst = @"...") or use isEqual:.

http://clang.llvm.org/docs/ObjectiveCLiterals.html

BTW: You should use collision free keys. MyKey does not fulfill this. Better use com.MyComponay.MyTarget.MyKey or a equivalent rDNS notation.

Amin Negm-Awad
  • 16,582
  • 3
  • 35
  • 50
  • Traditionally constant C strings and objc string literals are uniqued not only by the compiler but also by the *linker*. So comparing them using `==` in one app usually works. The place where this breaks is when comparing literals from different frameworks. – Nikolai Ruhe Apr 07 '15 at 09:31
1

void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);

There are three ways to set "const void *key" as the globally unique keyword. To sure there is one-to-one match between the const void *key and associated Object.

  • a static variable :&btnKey

  • @selector(methodName)

  • _cmd

1 . A static variable you set enter image description here

2 . @selector(methodName). enter image description here

3 . _cmd instead of @selector(methodName)

*_cmd* is the the current method of the selector in OC, the same as *self* 

is current method call the object instance.

enter image description here

Qun Li
  • 1,256
  • 13
  • 13
0

"It is often recommended that they key be a static char—or better yet, the pointer to one. Basically, an arbitrary value that is guaranteed to be constant, unique, and scoped for use within getters and setters

However, a much simpler solution exists: just use a selector.

objc_getAssociatedObject(self, @selector(associatedObject)) "

Refer to this for complete explanations on Associated Objects: http://nshipster.com/associated-objects/

Mepla
  • 438
  • 4
  • 16