iOS 给分类添加属性关联对象

iOS 给分类添加属性关联对象,第1张

分类里添加属性,仅仅是生成了set和get方法的声明,并没有实现,需要我们自己写set和get的方法。

几种set,get方法实现案例

1.可以全局字典实现属性的存取

//声明全局的字典

NSMutableDictionary *_names_

//load方法实现字典

+ (void)load

{

   _ names_ = [NSMutableDictionary dictionary]

}

//实现set方法

-(void)setName:(NSstring *)name

{

   NSString *key = [NSString stringWithFormat:@"%p", self]

    names_[MJKey] = name

}

//实现get方法

- (NSString *)name

{

//    NSString *key = [NSString stringWithFormat:@"%p", self]

    return names_[MJKey]

}

存在的问题:

全局变量无法释放 

如果每个类在不不同的线程,同时访问set和get,如果不不加锁,可能会出现问题

2.关联对象

- (void)setName:(NSString *)name

{

    objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC)

}

- (NSString *)name

{

    // 隐式参数

    // _cmd == @selector(name)

    return objc_getAssociatedObject(self, _cmd)

}

第四个参数为关联策略,和变量的对应关系

第二个参数key

第一种方法利用字符串作为key,其中利用@"string",这样写的字符串是放在常量区的,无论哪里用到都是同一内存同一地址,但是这样写容易写错,且编译器没有提醒

更推荐第二种写法,不容易记错其中@selector(name),_cmd_,是函数的隐式参数

实现关联对象技术的核心对象

AssociationsManager

AssociationsHashMap

ObjectAssociationMap

ObjectAssociation

其中AssociationsManager类管理了一个全局的散列表,key是添加管理属性的对象,value是ObjectAssociationMap的散列表,其中key是第二个参数,value是ObjectAssociation类,ObjectAssociation其中包含有value和policy,也就是我们传入的第三和第四个参数

关联对象并不是存储在被关联对象本身的内存中

关联对象存储在全局的同一的AssociationsManager中

设置关联对象为nil,相当于移出关联对象

原则上讲它只能添加方法, 不能添加属性(成员变量),实际上可以通过其它方式添加属性(Runtime)。

举个例子,给系统UIButton添加个model 属性 新建个分类文件

.h文件

.m文件 需要导入runtime头文件

日常开发过程中我们经常碰到要给分类添加自定义属性和变量的,下面通过关联对象给分类添加属性,也是runtime的实际应用之一,非常实用。(关于runtime的使用还有很多,这里只简单记录一下利用runtime给分类添加属性)。

关联Runtime提供了下面几个接口:

void objc_setAssociatedObject(id object, const void * key, id value, objc_AssociationPolicy policy)

id objc_getAssociatedObject(id object, const void * key)

void objc_removeAssociatedObjects(id object)

id object被关联的对象

const void * key:关联的key,要求唯一

id value:关联的对象

objc_AssociationPolicy policy:内存管理策略

1.给UILabel添加一个 竖直方向的verticalText,如下图所示:

新建一个继承UILabel的Category,并添加一个成员变量

.h文件

m.文件

调用时就直接使用点语法:

_textLabel.verticalText = @"厉害了,我的国"

2.给UIButton添加一个扩大点击区域的实例方法

新建一个继承UIButton的Category,并添加一个实例方法

.h文件

.m文件

创建button并调用:

[button setTouchExpandEdgeWithTop:30 right:30 bottom:30 left:30]

点击button的上下左右各30pt,button也会有响应。

Demo链接


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11770949.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-18
下一篇 2023-05-18

发表评论

登录后才能评论

评论列表(0条)

保存