如何执行关联参考? [英] How is Associative Reference implemented?

查看:98
本文介绍了如何执行关联参考?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里看到了一个很好的示例: 子类UIButton以添加属性

I saw a very good sample here: Subclass UIButton to add a property

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

What is it? You can't add object to a category. But now with this trick you can.

那是什么?如何运作?

objective-c对象已经具有一定数量的ivar指针了吗?

Objective-c object already have some constant number of ivar pointers right?

现在添加另一个吗?他们是怎么知道的?

Now you add another one? How did they figure that out?

我必须承认一个非常丑陋的符号.

A pretty ugly notation I must admit.

推荐答案

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

With the Associative References trick, you're not actually adding any instance data to the UIButton object. Instead, you're using a totally separate Cocoa facility to create a new dictionary mapping (or associating) existing UIButton objects with data that's stored elsewhere in the heap.

无需使用Cocoa的关联参考,您可以做完全相同的事情;它只会更难看,效率可能更低.在Objective-C ++中,它将像这样. (我什至不打算尝试在Objective-C中编写它,因为CFMutableDictionaryNSMutableDictionary在两个级别上都有错误的行为,并且我不会从头开始编写整个内容.但是,C ++的std::map不能与__weak一起使用我想要的引用方式,因此我会使用这种效率低下的std::vector算法.对于不熟悉C ++的人:std::vector大致等效到NSMutableArray,除非您可以选择是否保留其内容.)

You could do exactly the same thing without using Cocoa's Associative References; it would just be even uglier and probably less efficient. It would go something like this, in Objective-C++. (I'm not even going to try to write it in Objective-C, because CFMutableDictionary and NSMutableDictionary both have the wrong behavior on a couple of levels, and I'm not going to write the whole thing from scratch. However, C++'s std::map can't be used with __weak references the way I want to use it, so I'm falling back on this inefficient std::vector algorithm. For those unfamiliar with C++: std::vector is roughly equivalent to an NSMutableArray, except that you get to choose whether it retains its contents.)

重点是UIButton对象没有被更改;即将发生变化的是此附加词典的内容.属性getter和setter仅仅知道如何在字典中查找内容,以便出现,就像UIButton具有新属性一样.

The point is that the UIButton objects aren't being changed; what's changing is the contents of this additional dictionary. The property getter and setter simply know how to look things up in that dictionary so that it appears as if the UIButton has a new property.

#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/

这篇关于如何执行关联参考?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆