Category利用runtime的关联对象技术为其添加属性

什么叫关联对象技术?说通俗一点,我们都知道用Category类别可以给一些类添加方法,但是不能添加新属性,那怎么添加属性呢?一种直接的方法是继承,但如果只是为了添加一个属性就去做一次继承,还是有点重,这时候,就可以用关联对象的方法。

注意事项:

  1. 在分类中可以添加方法;
  2. 在分类中不能增加成员变量;
  3. 在分类中理论上不可以添加属性,但是利用runtime可以,这里属性不可以保留值,因为分类中没有成员变量,不会生成 _变量,不会自动实现settergetter方法,需要手动的实现settergetter方法;
  4. 在分类中可以重写原有类的方法,但是会覆盖掉原来的方法;
  5. 方法调用的优先级:分类-->原来的类-->父类;
  6. Category理论上不能添加变量,但是可以使用@dynamic 来弥补这种不足。
@dynamic variable;
- (id) variable
{
       return objc_getAssociatedObject(self, externVariableKey);
}
- (void)setVariable:(id) variable
{
    objc_setAssociatedObject(self, externVariableKey, variable, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
} 

所以我们可以利用 runtime来实现:

  1. 在程序运行时,动态的给对象添加属性:
  • objc_setAssociatedObject(<#id object#>, <#const void *key#>, <#id value#>, <#objc_AssociationPolicy policy#>)
// setter
-(void)setUrl1:(NSString *)url1
{
    /*参数:
     * id object 给哪个对象的属性赋值
     const void *key 属性对应的key
     id value  设置属性值为value
     objc_AssociationPolicy policy  使用的策略,是一个枚举值,和copy,retain,assign是一样的,手机开发一般都选择NONATOMIC
     */
    objc_setAssociatedObject(self, urlKey, url1, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
  1. 在程序运行时,动态的获取对象的属性:
  • objc_getAssociatedObject(<#id object#>, <#const void *key#>)
// getter
-(NSString *)url1
{
    return objc_getAssociatedObject(self, urlKey);
}
  1. 移除关联对象:
  • objc_removeAssociatedObjects(<#id object#>)
// 移除关联对象
-(void)dealloc
{
    objc_removeAssociatedObjects(self);
}

详情请戳:
Demo地址:https://github.com/Reminiscencexing/-Category-

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

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,135评论 1 32
  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,520评论 8 265
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,757评论 0 9
  • 胡天乐阅读 177评论 0 0
  • 前一段看奇葩来了,朋友说起张晓晗,就说到这本书了,朋友强烈推荐,说很好看!我估计十年前我看这本书或许会喜欢吧,矫情...
    萌小_小懒阅读 373评论 0 0