gpt4 book ai didi

objective-c - 避免关联对象键的额外静态变量

转载 作者:太空狗 更新时间:2023-10-30 03:12:09 26 4
gpt4 key购买 nike

当使用关联对象(从 iOS 4 和 OSX 10.6 开始可用的 Objective-C 运行时功能)时,有必要定义一个键来在运行时存储和检索对象。

典型的用法是像下面这样定义键

static char const * const ObjectTagKey = "ObjectTag";

然后就是用来存储对象

objc_setAssociatedObject(self, ObjectTagKey, newObjectTag, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

并取回它

objc_getAssociatedObject(self, ObjectTagKey);

(以 http://oleb.net/blog/2011/05/faking-ivars-in-objc-categories-with-associative-references/ 为例)

有没有更简洁的方法来定义关联的对象键,不涉及额外变量的声明?

最佳答案

根据这个blog entry由 Erica Sadun(其学分转到 Gwynne Raskind),有。

objc_getAssociatedObjectobjc_getAssociatedObject 需要一个键来存储对象。这样的键必须是一个常量 void 指针。所以最后我们只需要一个随时间保持不变的固定地址。

事实证明,@selector 实现提供了我们所需要的,因为它使用固定地址。

因此,我们可以去掉键声明并简单地使用我们属性的选择器地址。

因此,如果您在运行时关联一个属性,例如

@property (nonatomic, retain) id anAssociatedObject;

我们可以为其 getter/setter 提供动态实现,如下所示

- (void)setAnAssociatedObject:(id)newAssociatedObject {
objc_setAssociatedObject(self, @selector(anAssociatedObject), newAssociatedObject, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (id)anAssociatedObject {
return objc_getAssociatedObject(self, @selector(anAssociatedObject));
}

与为每个关联对象定义一个额外的静态变量键相比,非常简洁明了。

这样安全吗?

由于这是依赖于实现的,所以一个合理的问题是:它会轻易崩溃吗?引用博客条目

Apple would probably have to implement a completely new ABI for that to happen

如果我们相信这些话是真的,那么它就相当安全了。

关于objective-c - 避免关联对象键的额外静态变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16020918/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com