5

ここで非常に良いサンプルを見ました: プロパティを追加する UIButton をサブクラス化する

それは何ですか?オブジェクトをカテゴリに追加することはできません。しかし、このトリックを使えばできます。

それで、それは何ですか?それはどのように機能しますか?

Objective-c オブジェクトには、すでに一定数の ivar ポインターがありますよね?

今、あなたは別のものを追加しますか?彼らはどうやってそれを理解したのですか?

私が認めなければならないかなり醜い表記法。

4

2 に答える 2

6

連想参照のトリックでは、実際にはインスタンス データを 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/

于 2012-10-28T19:41:00.297 に答える