Objective-C动态添加property

今天接到一个需求,要在一个指定View的subViews中查找几个特定的View进行指定的操作,但是对于开发者来说,它们都是最普通的View,没有什么特殊型来与其它对象区分开来,这个问题困扰了我好一会,最好想到的办法是在需要特殊处理的View生成时给它指定一个特殊的ID,这样在后期查找是就可以判断出subViews数组中那些对象是我需要处理的。

实现这个功能最方便的方法是新建一个UIView的Category,并动态创建businessID属性。代码如下:

#import <UIKit/UIKit.h>

@interface UIView (Additions)

@property (copy,nonatomic) NSString *sdBusinessID;

@end
#import "UIView+Additions.h"
#import <objc/runtime.h>

static const char *kBusinessID = "com.sd.businessID";

@implementation UIView (Additions)

- (void)setSdBusinessID:(NSString *)sdBusinessID
{
    objc_setAssociatedObject(self,
                             kBusinessID,
                             sdBusinessID,
                             OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)sdBusinessID
{
    return objc_getAssociatedObject(self, kBusinessID);
}

@end

如上就实现了动态设置property的功能,导入头文件即可使用。

在实现代码中我们用到了runtime中的两个方法,函数原型如下:

/** 
 * Sets an associated value for a given object using a given key and association policy.
 * 
 * @param object The source object for the association.
 * @param key The key for the association.
 * @param value The value to associate with the key key for object. Pass nil to clear an existing association.
 * @param policy The policy for the association. For possible values, see “Associative Object Behaviors.”
 * 
 * @see objc_setAssociatedObject
 * @see objc_removeAssociatedObjects
 */
OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
    OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0);

/** 
 * Returns the value associated with a given object for a given key.
 * 
 * @param object The source object for the association.
 * @param key The key for the association.
 * 
 * @return The value associated with the key \e key for \e object.
 * 
 * @see objc_setAssociatedObject
 */
OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key)
    OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0);

我们首先来了解一下设置property的方法objc_setAssociatedObject。其中第一个参数object为要操作的对象;第二个参数key为存储/获取属性的key;第三个参数value为要保存的数据;第四个参数为访问策略,需要传入枚举值,具体如下:

typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
    OBJC_ASSOCIATION_ASSIGN = 0,           /**< Specifies a weak reference to the associated object. */
    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**< Specifies a strong reference to the associated object. 
                                            *   The association is not made atomically. */
    OBJC_ASSOCIATION_COPY_NONATOMIC = 3,   /**< Specifies that the associated object is copied. 
                                            *   The association is not made atomically. */
    OBJC_ASSOCIATION_RETAIN = 01401,       /**< Specifies a strong reference to the associated object.
                                            *   The association is made atomically. */
    OBJC_ASSOCIATION_COPY = 01403          /**< Specifies that the associated object is copied.
                                            *   The association is made atomically. */
};

通过枚举的名称我们就可以知道其功能,主要对应retain nonatomic、retain等,使用时可参照对应的注释选择自己需要的。

读取property值的方法比较简单,只要将操作对象与key传入参数即可。

另外还有一点需要注意,Category在扩展类的同时也存在与系统方法或第三方库中Category方法冲突的问题,在方法命名时可以加入特定的前缀或后缀来规避这一问题。

转载于:https://my.oschina.net/wangshitou/blog/719264

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值