在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里,你可以为一个对象添加键/值对,然后可以用下面两

个方法来对它进行存取:

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_ASSIGNOBJC_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;
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值