CategoriesでAssociative Referencesを使用してclassに擬似インスタンス変数を追加
ios 3.1とos x 10.6システムでは、アップル社がobjective-cの実行時にassociative referencesを追加しました.
プロパティ.本質的には、オブジェクトごとにoptional dictionaryがあることを意味します.このdictionaryでは
の双曲線コサインを返します.
これは強力な特性であり、特にobjective-cが本来持っていたcategories特性を考慮すると.しかし、
categoriesでは、クラスに追加のインスタンス変数を追加することはできません.associative referencesを使用してクラスに擬似を追加
インスタンス変数は非常に容易になります.
objective-c実行時に提供されるc言語のapiでは、1つのオブジェクトにキー/値ペアを追加し、次の2つを使用できます.
アクセスする方法は次のとおりです.
上記のメソッドの呼び出しをプロパティのカスタムgetterとsetterメソッドにパッケージすると、apiを使用するユーザーに
完全に不透明な擬似インスタンス変数を実現した.
Using objects to tag UIViews
プロパティ.本質的には、オブジェクトごとにoptional dictionaryがあることを意味します.このdictionaryでは
の双曲線コサインを返します.
これは強力な特性であり、特にobjective-cが本来持っていたcategories特性を考慮すると.しかし、
categoriesでは、クラスに追加のインスタンス変数を追加することはできません.associative referencesを使用してクラスに擬似を追加
インスタンス変数は非常に容易になります.
objective-c実行時に提供されるc言語のapiでは、1つのオブジェクトにキー/値ペアを追加し、次の2つを使用できます.
アクセスする方法は次のとおりです.
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) id objc_getAssociatedObject(id object, const void *key)
上記のメソッドの呼び出しをプロパティのカスタムgetterとsetterメソッドにパッケージすると、apiを使用するユーザーに
完全に不透明な擬似インスタンス変数を実現した.
Using objects to tag UIViews
次の例では、viewのtagとしてオブジェクトを追加したいと考えています(UIViewにすでに存在するtag属性は
intergersタイプのデータを受信すると、制約要因になる場合があります).
次のように「object tag」categoryのクラスを書きます.@interface UIView (ObjectTagAdditions)
@property (nonatomic, retain) id objectTag;
- (UIView *)viewWithObjectTag:(id)object;
@end
associative referencesを使用すると、プロパティの実装は非常に直接的です.static const char *ObjectTagKey = "ObjectTag";
@implementation UIView (ObjectTagAdditions)
@dynamic objectTag;
- (id)objectTag {
return objc_getAssociatedObject(self, ObjectTagKey);
}
- (void)setObjectTag:(id)newObjectTag {
objc_setAssociatedObject(self, ObjectTagKey, newObjectTag, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
...
setメソッドでOBJC_を指定することでASSOCIATION_RETAIN_NONATOMIC、コンパイラに実行時retainを教えてくれました
この変数の値.その他指定できる表示は、OBJC_ASSOCIATION_ASSIGN
・、OBJC_ASSOCIATION_COPY_NONATOMIC
、OBJC_ASSOCIATION_RETAIN
、OBJC_ASSOCIATION_COPY; 。
, -viewWithObjectTag:method: , objectTag view:
- (UIView *)viewWithObjectTag:(id)object {
// Raise an exception if object is nil
if (object == nil) {
[NSException raise:NSInternalInconsistencyException format:@"Argument to -viewWithObjectTag: must not be nil"];
}
// Recursively search the view hierarchy for the specified objectTag
if ([self.objectTag isEqual:object]) {
return self;
}
for (UIView *subview in self.subviews) {
UIView *resultView = [subview viewWithObjectTag:object];
if (resultView != nil) {
return resultView;
}
}
return nil;
}
@interface UIView (ObjectTagAdditions)
@property (nonatomic, retain) id objectTag;
- (UIView *)viewWithObjectTag:(id)object;
@end
static const char *ObjectTagKey = "ObjectTag";
@implementation UIView (ObjectTagAdditions)
@dynamic objectTag;
- (id)objectTag {
return objc_getAssociatedObject(self, ObjectTagKey);
}
- (void)setObjectTag:(id)newObjectTag {
objc_setAssociatedObject(self, ObjectTagKey, newObjectTag, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
...
- (UIView *)viewWithObjectTag:(id)object {
// Raise an exception if object is nil
if (object == nil) {
[NSException raise:NSInternalInconsistencyException format:@"Argument to -viewWithObjectTag: must not be nil"];
}
// Recursively search the view hierarchy for the specified objectTag
if ([self.objectTag isEqual:object]) {
return self;
}
for (UIView *subview in self.subviews) {
UIView *resultView = [subview viewWithObjectTag:object];
if (resultView != nil) {
return resultView;
}
}
return nil;
}