objc_setAssociatedObject的键不断更改地址

时间:2011-07-27 16:28:10

标签: objective-c cocoa

我正在尝试创建一个用于objc_setAssociatedObject的密钥,就像这个问题一样:

How do I use objc_setAssociatedObject/objc_getAssociatedObject inside an object?

我有一个定义

的MyConstants.h文件
static NSString *myConstant = @"MyConstant";

然后通过MyFramework.h将此文件包含在MyFramework中

#import ...;
#import "MyConstants.h"
#import ...;

然后在我的项目中,框架通过.pch标题包含在所有文件中。

#import <Cocoa/Cocoa.h>
#import <MyFramework/MyFramework.h>

这一切都按预期工作。问题是当我用myConstant作为键调用objc_setAssociatedObject或objc_getAssociatedObject时,它不起作用。原因很简单:

- (void)doSomething:(id)key { //Gets called with myConstant
    NSLog(@"Associating with key at %p", &key);
    objc_setAssociatedObject(self, &key, object, policy);
}
- (void)doSomethingElse:(id)key { //Gets called with myConstant
    NSLog(@"Seeking association for key at %p", &key);
    NSLog(@"Will find %@", objc_getAssociatedObject(self, &key));
}

哪些日志:

Associating with key at 0x7fff5fbfecdf
Seeking association for key at 0x7fff5fbfecef
Will find (null)

你会注意到指针移动了。

但是,再次调用相同的方法会显示相同的指针。就好像常量是常量,在导入它的文件中,但不是整个项目

问:如何正确定义和导入包含常量的标题,以便常量实际上在内存中的常量位置?

2 个答案:

答案 0 :(得分:9)

如果两个文件有static char something,则每个文件都有自己的副本 - 它们不代表同一块内存。如果您希望两个文件可以访问密钥,则必须在标题中执行此操作:

extern const char MyConstantKey;

这在一个实现文件(.c或.m)中:

const char MyConstantKey;

这在内存中定义了一个 - char - 宽的位置,当您使用&MyConstantKey时,所有文件都会指向该位置。

答案 1 :(得分:0)

我已经编辑了原帖,以显示我认为错误是什么。另一张海报的答案也可能是一个很好的解决方案,但我如何解决问题是这样的:

正如&amp;键所示,我将密钥直接传递给方法,如myMethod:(id)键。不知何故,取消引用此指针在不同情况下是不同的。只需将所有方法更改为myMethod:(void *)键并在&amp;键中传递,问题就会立即消失。或者确保我使用静态字符而不是静态NSString *

我不完全理解它,但它有效。