几种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,如果不不加锁,可能会出现问题
- (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的实际应用之一,非常实用。(关于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链接
1、不能在分类中添加实例变量的原因
因为分类的本质也是结构体,这里没有实例变量的列表,添加进去存不了。(个人理解)
2、实际 *** 作检查的结果
1)创建分类的.h和.m文件
.h文件
.m文件(使用关联对象实现setter和getter方法)
2)打印类的实例变量列表
3)打印结果
从打印结果可以看出,time属性添加成功,getter和setter方法也实现了,touchesBegan方法点击也有响应,但是类的实例变量列表里没有_time。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)