Ano*_*ite 6 associative objective-c
我在这里看到了一个非常好的示例: 子类UIButton来添加属性
它是什么?您无法将对象添加到类别.但现在有了这个技巧你可以.
那是什么?它是如何工作的?
Objective-c对象已经有一些常数的ivar指针了吗?
现在你再添加一个?他们是怎么想出来的?
我必须承认,这是一个非常丑陋的符号.
使用“关联引用”技巧,您实际上并没有向UIButton对象添加任何实例数据。相反,您使用的是完全独立的Cocoa工具来创建新的字典映射,或者将现有的UIButton对象与存储在堆中其他位置的数据进行关联。
您无需使用Cocoa的关联参考就可以做完全相同的事情。它甚至更丑陋,效率可能更低。在Objective-C ++中,它将像这样。(我甚至没有去尝试把它写在Objective-C,因为CFMutableDictionary和NSMutableDictionary两者都会对几个级别的错误行为,我不打算从头开始写了整个事情。但是,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
Run Code Online (Sandbox Code Playgroud)
另请参阅:http : //labs.vectorform.com/2011/07/objective-c-associated-objects/
| 归档时间: |
|
| 查看次数: |
2139 次 |
| 最近记录: |