iOS中的Ivar和属性有什么关系?category能不能添加属性?

1.Ivar

typedef objc_ivar * Ivar;
  struct objc_ivar {
     char *ivar_name;
     char *ivar_type;
     int ivar_offset;
  #ifdef __LP64__
     int space;
  #endif
  }

Ivar其实是一个objc_ivar的指针,objc_ivar是一个struct,其中包含变量名、变量类型。
Ivar实例变量所在内存区域初始化后不可更改,无法在运行时增加实例变量,所以分类是无法添加实例变量的。

2.属性

当我们为类添加属性时,其实自动生成了getter、setter和Ivar。其实property = Ivar + getter + setter。
但是分类中无法添加实例变量,所以直接添加属性无法自动生成getter和setter。必须自己实现这两个方法。这种属性被称为关联属性。

static const void *tagKey = &tagKey;//自定义的关联标识

//setter
-(void)setTestProperty:(NSString *)testProperty{
    objc_setAssociatedObject(self, tagKey, testProperty, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

//getter
-(NSString *)testProperty{
    //根据tagKey, 返回关联属性value
   return objc_getAssociatedObject(self, tagKey);
}

总结

在category中无法添加实例变量,也无法直接添加属性。必须通过关联属性的方式添加。由于关联属性是动态存取的,如果碰到bug极难查找,所以若非必要尽量不要在分类中增加属性。

你可能感兴趣的:(iOS中的Ivar和属性有什么关系?category能不能添加属性?)