Objective-C动态添加property
Objective-C动态添加property
王石头 发表于1年前
Objective-C动态添加property
  • 发表于 1年前
  • 阅读 73
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

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

今天接到一个需求,要在一个指定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方法冲突的问题,在方法命名时可以加入特定的前缀或后缀来规避这一问题。

共有 人打赏支持
粉丝 9
博文 24
码字总数 26001
×
王石头
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: