我一直在使用objc_setAssociatedObject():
objc_setAssociatedObject(myObject, @"myKey1", obj2, OBJC_ASSOCIATION_ASSIGN);
特别是,我的键是一个字符串,因此编译器使用指向该字符串的指针。我在objc_getAssociatedObject()中指定了相同的字符串:
objc_getAssociatedObject(myObject, @"myKey1").
我已经使用这个方案很长一段时间没有任何问题。但是,SO上的示例使用指向静态变量的指针,所以我现在意识到我的方法可能不正确。编译器每次都使用相同的指针,因此它始终有效。
我的方法可以吗?它似乎等同于使用指向静态字符串的指针。在什么情况下编译器可以存储我的密钥的两个不同副本?
答案 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 *key
和associated Object
之间存在一对一的匹配。
静态变量:&btnKey
@selector(methodName)
_cmd
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.
答案 2 :(得分:0)
“通常建议将键设置为静态字符 - 或者更好,指向一个字符串。基本上,保证在getter和setter中使用的任意值是常量,唯一和范围
但是,存在一个更简单的解决方案:只需使用选择器。
objc_getAssociatedObject(self, @selector(associatedObject))
“
有关关联对象的完整说明,请参阅此处:http://nshipster.com/associated-objects/