美文网首页
iOS:通过runtime为category添加属性

iOS:通过runtime为category添加属性

作者: Waynee | 来源:发表于2018-04-10 19:06 被阅读24次

    本人虽然在项目中没有遇见需要给一个类的分类添加属性的情况,但在面试的过程中却被问到过。所以下面给出自己的拙见,若有不足,还请读者给出自己不同的意见。

    首先:当给一个类的category添加一个属性:name。此时系统不会给此属性添加setter和getter方法,所以当在外界调用的时候会因为找不到该setter方法而crash([Person setName:]: unrecognized selector sent to instance);此时我们只需要在.m文件中实现对应的两种方法即可,因为此时无法直接用_name 接受外界传来值。所以选择了用runtime建立关联的方式。

    先导入头文件<objc/runtime.h>

    objc_setAssociatedObject(id_Nonnullobject,constvoid*_Nonnullkey, id_Nullablevalue, objc_AssociationPolicy policy),这个方法有四个参数,依次为:1:源对象。 2:关联时的用来标记是哪一个属性的key,此处用的是静态变量key的内存地址,也可保证唯一性。3:关联的对象(一般也是需要用到的值)。4:关联方式。

    第四个关联参数一共四个枚举值,个人理解为

    enum{ OBJC_ASSOCIATION_ASSIGN =0,// 看成修饰词(atomic, assign)

    OBJC_ASSOCIATION_RETAIN_NONATOMIC =1,//(nonatomic, strong)

    OBJC_ASSOCIATION_COPY_NONATOMIC =3,//(nonatomic, copy)

    OBJC_ASSOCIATION_RETAIN =01401,//(atomic, strong)

    OBJC_ASSOCIATION_COPY =01403//(atomic, copy)

    }

    objc_getAssociatedObject(id_Nonnullobject,constvoid*_Nonnullkey)此方法返回的其实就是上面objc_setAssociatedObject方法的第三个参数。参数对应上面的:1:源对象。 2:关联时的用来标记是哪一个属性的key。跟objc_setAssociatedObject中的值保持一致。

    示例代码如下:

    *********************Person+Extension.h**************************

    #import "Person.h"

    @interfacePerson (Extension)

    @property (nonatomic, copy) NSString *name;

    @end

    *********************Person+Extension.m**************************

    #import "Person+Extension.h"

    @interface Person ()

    @property (nonatomic, copy) NSString *personId;

    @end

    staticvoid*key = &key; // 也可以用这种方式 :staticNSString*Key =@"xxxKey";

    @implementationPerson (Extension)

    - (void)setName:(NSString*)name{

        objc_setAssociatedObject(self,

     key,

     name,

    OBJC_ASSOCIATION_COPY_NONATOMIC);

    }

    - (NSString*)name{

        return objc_getAssociatedObject(self, key);

    }

    @end

    ***********************************

    - (void)viewDidLoad {

        [super viewDidLoad];

        person.name=@"xxx";

        NSLog(@"%@", person.name);

    }

    /////// 打印结果:xxx ///////

    相关文章

      网友评论

          本文标题:iOS:通过runtime为category添加属性

          本文链接:https://www.haomeiwen.com/subject/eedehttx.html