赞
踩
对象 在我们运行的时候,他是一个C语言的结构体,它的结构是
typedef struct objc_object *id;
struct objc_object {
Class isa;
};
它的isa指针指向它自己的类
类 在我们运行的时候,他是一个C语言的结构体,它的结构是
typedef struct objc_class *Class;
struct objc_class {
Class isa; // 指向它的元类(NSObject)
Class super_class; // 指向它的父类
const char *name; // 指向它的类名
long version; // 指向类的版本
long info; // 指向类的信息
long instance_size; // 指向它创建对象的占用内存
struct objc_ivar_list *ivars; // 指向它的所有成员变量
struct objc_method_list **methodLists; // 指向它的所有方法
struct objc_cache *cache ; // 指向它的缓存方法
struct objc_protocol_list *protocols; // 指向它的属性链表
};
方法 在我们运行的时候,他是一个C语言的结构体,它的结构是
typedef struct objc_method *Method;
struct objc_method {
SEL method_name; // 指向方法的名字
char *method_types; // 指向方法的类型(类方法,实例方法)
IMP method_imp; // 指向方法的内存
};
类别.....
struct objc_category {
char *category_name;
char *class_name ;
struct objc_method_list *instance_methods ;
struct objc_method_list *class_methods ;
struct objc_protocol_list *protocols ;
}
介绍下用到的 运行时的方法,
1.const char * class_getName(Class cls) 返回值 类的名字 ,当传入nil 是传回来是空字符串
NSStringFromClass([self class]) : 获取类的类名
简单实用例子
在
ViewController里写 (场景)
class_getName([self class]); // 打印 ViewController 注意是 返回的char *
NSStringFromClass([self class]) // 打印 ViewController 是一样的, 只是这个是OC字符串罢了
2.void objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy)
id objc_getAssociatedObject (id object, void *key) 这两方法是结合着用的,就相当于先set 再get 。我觉得可以理解为,objc_setAssociatedObject 就是创建了一个对象,这个对象就是同个void *key 把id value 创建出来,同个这种关联的方式能让这个值 与id object, 同生命周期,objc_getAssociatedObject这个方法是就是通过void *key 获取前面关联的值,(理解为创建的值也行)
有四个参数
1.被关联的对象 id object
2.要关联的对象的键值,一般设置成静态的,用于获取关联对象的值 void *key 通过这个key 可以获取关联的值
3.要传得值 一般是静态变量 id value 就是将要关联的值
4.关联时采用的协议,有assign,retain,copy等协议 点击进去选取枚举 objc_AssociationPolicy policy
举一个简单使用例子
static const char associatedkey;
NSString *string =@"haha";
// 关联,创建对象
NSString *master = @"Raines";
// 通过两个对象间的联合把两个对象绑定在一起
objc_setAssociatedObject(string, &mkey, master, OBJC_ASSOCIATION_COPY_NONATOMIC);
// 读取联合对象的值
NSString *RainesStr = objc_getAssociatedObject(string, &mkey); // 这个 NSString *RainesStr 打印的值就是 NSString *master 的值
刚开始觉得这个方法是多此一举, 就只有让关联控件同生命周期。
后面发现,这个方法还是好用的。比如你要重写get方法。 在category 增加属性,就可以用这种方式进行添加 。
举个 明杰哥 刷新的一个例子
场景是在(@implementation UIScrollView (MJRefresh))在一个分类中,
static const char MJRefreshHeaderKey = '\0';
- (void)setMj_header:(MJRefreshHeader *)mj_header
{
if (mj_header != self.mj_header) {
// 删除旧的,添加新的
[self.mj_header removeFromSuperview];
[self insertSubview:mj_header atIndex:0];
// 存储新的
[self willChangeValueForKey:@"mj_header"]; // KVO
objc_setAssociatedObject(self, &MJRefreshHeaderKey,
mj_header, OBJC_ASSOCIATION_ASSIGN);
[self didChangeValueForKey:@"mj_header"]; // KVO
}
}
- (MJRefreshHeader *)mj_header
{
return objc_getAssociatedObject(self, &MJRefreshHeaderKey);
}
动态的返回了创建的mj_header 还让他们同生命周期太nice了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。