我在这里看到了一个非常好的示例:子类 UIButton 添加属性
它是什么?您无法将对象添加到类别。但现在有了这个技巧你就可以了。
那么它是什么?它是如何工作的?
Objective-c 对象已经有一些恒定数量的 ivar 指针,对吗?
现在你再加一个吗?他们是怎么想出来的?
我必须承认这是一个相当丑陋的符号。
使用关联引用技巧,您实际上并没有添加任何实例数据到 UIButton 对象。相反,您使用完全独立的 Cocoa 工具来创建新的字典映射(或联想) 现有的 UIButton 对象以及存储在堆中其他位置的数据。
您可以在不使用 Cocoa 的关联引用的情况下做完全相同的事情;它只会变得更加丑陋并且可能效率更低。在 Objective-C++ 中,它会是这样的。 (我什至不打算尝试用 Objective-C 编写它,因为CFMutableDictionary
and NSMutableDictionary
两者在几个层面上都有错误的行为,我不会从头开始写整个事情。然而,C++ 的std::map
不能与__weak
引用了我想要使用它的方式,所以我依靠这种低效的方式std::vector
算法。对于那些不熟悉 C++ 的人:std::vector
大致相当于NSMutableArray
,但您可以选择是否保留其内容。)
重点是 UIButton 对象没有被改变;改变的是这个附加字典的内容。属性 getter 和 setter 只是知道如何在字典中查找内容,以便它appears就像 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-linked-objects/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)