【问题标题】:Proper key format for objc_setAssociatedObject()objc_setAssociatedObject() 的正确键格式
【发布时间】:2015-04-07 08:40:22
【问题描述】:

我一直以这种方式使用 objc_setAssociatedObject():

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

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

objc_getAssociatedObject(myObject, @"myKey1").

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

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

【问题讨论】:

标签: ios objective-c


【解决方案1】:

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

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

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

顺便说一句:您应该使用无冲突键。 MyKey 不满足这一点。最好使用 com.MyComponay.MyTarget.MyKey 或等效的 rDNS 表示法。

【讨论】:

  • 传统的常量 C 字符串和 objc 字符串文字不仅由编译器唯一,而且由 链接器 唯一。因此,在一个应用程序中使用== 比较它们通常是有效的。当比较来自不同框架的文字时,会出现这种情况。
【解决方案2】:

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

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

  • 一个静态变量:&btnKey

  • @selector(methodName)

  • _cmd

1 . A static variable you set

2 。 @selector(methodName)

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.

【讨论】:

  • 你有 swift 等效的选择器方法吗?
【解决方案3】:

“通常建议它们的键是静态字符,或者更好的是指向一个字符的指针。基本上,一个任意值,保证在 getter 和 setter 中使用是恒定的、唯一的和作用域

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

objc_getAssociatedObject(self, @selector(associatedObject)) "

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

【讨论】:

    猜你喜欢
    • 2018-01-06
    • 2017-05-29
    • 1970-01-01
    • 2013-03-14
    • 2014-11-20
    • 1970-01-01
    • 2017-10-04
    • 1970-01-01
    • 2021-11-07
    相关资源
    最近更新 更多