iOS Runtime应用实例——类别添加属性

为分类添加属性

如果我们直接给分类添加属性,然后去访问程序就会闪退,因为分类中需要我们自己去写这个属性的set和get方法。

为分类中添加属性需要使用到runtime.h中的俩个方法
这两个方法是为一个对象设置关联对象,等价于添加一个属性

objc_setAssociatedObject
objc_getAssociatedObject

UIView+ZCCExtension.h

#import <UIKit/UIKit.h>

@interface UIView (ZCCExtension)
@property (nonatomic, strong) NSString *zcc_name;
@end

UIView+ZCCExtension.m

#import "UIView+ZCCExtension.h"
#import <objc/runtime.h>
static const char kZCCName;

@implementation UIView (ZCCExtension)

- (NSString *)zcc_name {
     return objc_getAssociatedObject(self, &kZCCName);
}

- (void)setZcc_name:(NSString *)zcc_name {
    objc_setAssociatedObject(self, &kZCCName,zcc_name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
@end

在这里有必要解释两个问题:

  1. 为什么向方法中传入 key?

通常都是会采用静态变量来作为关键字,比如static const char kZCCName; 这里key我也查看了一些网上的解释,可以简单理解为关联对象中的对象相当于字典中的value,key相当于字典中的key。根据key可以取到你关联的对象

  1. OBJC_ASSOCIATION_RETAIN_NONATOMIC 是干什么的?
objc_AssociationPolicy modifier
OBJC_ASSOCIATION_ASSIGN assign
OBJC_ASSOCIATION_RETAIN_NONATOMIC nonatomic, strong
OBJC_ASSOCIATION_COPY_NONATOMIC nonatomic, copy
OBJC_ASSOCIATION_RETAIN atomic, strong
OBJC_ASSOCIATION_COPY atomic, copy

注意事项

添加的属性要增加前缀,例如我上文添加的使用了ZCC前缀,原因很简单,开发中难免要用到第三方库,不要和第三方库混淆。同时,iOS SDK会更新,也要确保不要和apple以后的属性名字冲突。
添加的属性可以是IBInspectable,IBOutlet等。例如,把上文中的改成IBInspectable,

@property (copy,nonatomic) IBInspectable NSString *zcc_name;

应用场景

想添加属性,但是又不想继承的场景。大部分是为了扩展iOS SDK中的类,比如UIView,UIViewController。

继承的缺点很明显,加入一个用户已经写好了一堆代码,那么每次使用子类导致了他的修改很多。而实用类别,对原有代码几乎没有影响。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容