objc_setAssociatedObject()的正确密钥格式

时间:2015-04-07 08:40:23

标签: ios objective-c

我一直在使用objc_setAssociatedObject():

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

特别是,我的键是一个字符串,因此编译器使用指向该字符串的指针。我在objc_getAssociatedObject()中指定了相同的字符串:

objc_getAssociatedObject(myObject, @"myKey1").

我已经使用这个方案很长一段时间没有任何问题。但是,SO上的示例使用指向静态变量的指针,所以我现在意识到我的方法可能不正确。编译器每次都使用相同的指针,因此它始终有效。

我的方法可以吗?它似乎等同于使用指向静态字符串的指针。在什么情况下编译器可以存储我的密钥的两个不同副本?

3 个答案:

答案 0 :(得分:1)

实际上,如果两个相等的字符串常量在同一个翻译单元中使用,则它们具有相同的地址。 (TU是来自C的术语,基本上它意味着:"相同的.m文件"。)但是这种行为不能保证,并且将来可能会改变。

  

这个警告也适用于编译时字符串文字。从历史上看,字符串文字(使用@" ..."语法)在链接期间在翻译单元中是唯一的。这是编译器的实现细节,不应该依赖它。如果您正在使用此类代码,请使用全局字符串常量(NSString * const MyConst = @" ...")或使用isEqual:。

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

BTW:您应该使用无冲突密钥。 MyKey无法满足此要求。更好地使用com.MyComponay.MyTarget.MyKey或等效的rDNS表示法。

答案 1 :(得分:1)

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

有三种方法可以设置" const void *key"作为全球唯一的关键字。确保const void *keyassociated Object之间存在一对一的匹配。

  • 静态变量:&btnKey

  • @selector(methodName)

  • _cmd

1。 A static variable you set enter image description here

2。 @selector(methodName)enter image description here

3。 _cmd代替@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

答案 2 :(得分:0)

“通常建议将键设置为静态字符 - 或者更好,指向一个字符串。基本上,保证在getter和setter中使用的任意值是常量,唯一和范围

但是,存在一个更简单的解决方案:只需使用选择器。

objc_getAssociatedObject(self, @selector(associatedObject))

有关关联对象的完整说明,请参阅此处:http://nshipster.com/associated-objects/