gpt4 book ai didi

objective-c - 关联引用是如何实现的?

转载 作者:太空狗 更新时间:2023-10-30 03:53:21 24 4
gpt4 key购买 nike

我在这里看到了一个很好的示例: Subclass UIButton to add a property

这是什么?您不能将对象添加到类别中。但现在有了这个技巧,您就可以了。

那是什么?它是如何工作的?

Objective-c 对象已经有一些常量的 ivar 指针对吧?

现在你又加了一个?他们是怎么想出来的?

我必须承认这是一个非常丑陋的符号。

最佳答案

使用关联引用技巧,您实际上并没有向 UIButton 对象添加任何实例数据。相反,您使用完全独立的 Cocoa 工具来创建新的字典映射(或关联)现有 UIButton 对象与存储在堆中其他位置的数据。

您可以在不使用 Cocoa 的关联引用的情况下做完全相同的事情;它只会更丑陋,而且效率可能更低。在 Objective-C++ 中,它会像这样。 (我什至不打算尝试用 Objective-C 编写它,因为 CFMutableDictionaryNSMutableDictionary 在几个层面上都有错误的行为,而且我不会从头开始写整个东西。但是,C++ 的 std::map 不能以我想要的方式与 __weak 引用一起使用,所以我我回到了这种低效的 std::vector 算法。对于那些不熟悉 C++ 的人:std::vector 大致等同于 NSMutableArray,除了您可以选择是否保留其内容。)

重点是 UIButton 对象没有被改变;发生变化的是这本附加词典的内容。属性 getter 和 setter 只知道如何在该字典中查找内容,以便它看起来就像 UIButton 具有新属性一样。

#import "UIButton+Property.h"
#import <algorithm>
#import <vector>

typedef std::pair<__weak id, __strong id> EntryType;
static std::vector<EntryType> myAR;

@implementation UIButton(Property)

-(void) setProperty:(id)property
{
for (int i=0; i < myAR.size(); ++i) {
if (myAR[i].first == self) {
myAR[i].second = property;
return;
}
}
myAR.push_back(EntryType(self, property));
}

-(id) property
{
/* To save space, periodically erase the dictionary entries for
* UIButton objects that have been deallocated. You can skip this
* part, and even use NSMutableDictionary instead of this C++
* stuff, if you don't care about leaking memory all over the place.
*/
size_t n = myAR.size();
for (size_t i=0; i < n; ++i) {
if (myAR[i].first == nil)
myAR[i] = myAR[--n];
}
myAR.resize(n);

/* Look up "self" in our dictionary. */
for (size_t i=0; i < myAR.size(); ++i) {
EntryType &entry = myAR[i];
if (entry.first == self) {
return entry.second;
}
}
return nil;
}

@end

另请参阅:http://labs.vectorform.com/2011/07/objective-c-associated-objects/

关于objective-c - 关联引用是如何实现的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13109042/

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