oc 元类 元数据
来源:互联网 发布:c 验证码识别 源码 编辑:程序博客网 时间:2024/05/03 10:07
首先认清一些概念。
struct objc_object { Class isa;};typedef struct objc_object *id;
struct objc_class { Class isa; 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;};typedef struct objc_class *Class;
此结构体可以储存类的诸多信息,例如类型名、父类类型、实例变量列表、方法列表等,这些信息被称作类的元数据(metadata)
。该结构体也有一个Class类型的成员isa,说明Class本身也是一个OC对象(被称为类对象或类型对象),而它的对象类型(isa所指向的类型)被称为元类(metaclass)
,元类中储存的是类对象的元数据,比如类方法就储存在这里。每个类可以有无数个对象,但仅有一个类对象,也仅有一个与之对应的元类。
object_getClass(obj)与[obj class]区别?
object_getClass(obj)返回的是obj中的isa指针;而[obj class]则分两种情况:一是当obj为实例对象时,[obj class]中class是实例方法:- (Class)class,返回的obj对象中的isa指针;二是当obj为类对象(包括元类和根类以及根元类)时,调用的是类方法:+ (Class)class,返回的结果为其本身。
Class f = object_getClass([sunClasssuperclass]);
Class g = object_getClass([[sunClasssuperclass] class]);
f == g
metaSunClass * sunClass = [[metaSunClass alloc] init]; Class a = object_getClass(object_getClass([sunClass class])); Class b = object_getClass(object_getClass([[sunClass superclass] class]));//此时 a == b 证明上图最右侧虚线元类的class是root[既:NSObject]。
下面的测试代码,是用来获取实例对象的方法和相应的元类方法,证明上图流程。
@interface metaBaseClass : NSObject { NSInteger iNum;}@property (assign, nonatomic, readonly ) NSInteger uNum;- (NSInteger) getINumber;- (void) setINumber:(NSInteger) num;+ (void)printILog;+ (void)printIILog;@end
@implementation metaBaseClass- (NSInteger) getINumber { return iNum;}- (void) setINumber:(NSInteger) num { iNum = num;}+ (void)printILog { NSLog(@"show log");}+ (void)printIILog { NSLog(@"show II log");}@end
@interface metaSunClass : metaBaseClass { NSInteger yNum;}@property (assign, nonatomic, readonly ) NSInteger uYNum;- (NSInteger) getYNumber;- (void) setYNumber:(NSInteger) num;+ (void)printYLog;@end
@implementation metaSunClass- (NSInteger) getYNumber { return yNum;}- (void) setYNumber:(NSInteger) num { yNum = num;}+ (void)printILog { NSLog(@"show Y log");}+ (void)printYLog { NSLog(@"show YY log");}@end
Method * mm = class_copyMethodList([sunClass class], &count); NSLog(@"%u",count); for(int j =0; j < count; j++) { Method mt = mm[j]; SEL sel =method_getName(mt); NSString *strName = [NSString stringWithCString:sel_getName(sel)encoding:NSUTF8StringEncoding]; NSLog(@"%@",strName); }
打印结果如下:
2016-05-16 20:17:03.698 test[17841:1055828] 3
2016-05-16 20:17:03.698 test[17841:1055828] getYNumber
2016-05-16 20:17:03.699 test[17841:1055828] setYNumber:
2016-05-16 20:17:03.699 test[17841:1055828] uYNum
Method * mm = class_copyMethodList([[sunClass superclass] class], &count); NSLog(@"%u",count); for(int j =0; j < count; j++) { Method mt = mm[j]; SEL sel =method_getName(mt); NSString *strName = [NSString stringWithCString:sel_getName(sel)encoding:NSUTF8StringEncoding]; NSLog(@"%@",strName); }
2016-05-16 20:17:49.717 test[17863:1056796] 3
2016-05-16 20:17:49.717 test[17863:1056796] getINumber
2016-05-16 20:17:49.717 test[17863:1056796] setINumber:
2016-05-16 20:17:49.717 test[17863:1056796] uNum
Method * mm = class_copyMethodList(object_getClass([sunClassclass]), &count); NSLog(@"%u",count); for(int j =0; j < count; j++) { Method mt = mm[j]; SEL sel =method_getName(mt); NSString *strName = [NSString stringWithCString:sel_getName(sel)encoding:NSUTF8StringEncoding]; NSLog(@"%@",strName); }
2016-05-16 20:19:21.936 test[17888:1058041] 2
2016-05-16 20:19:21.936 test[17888:1058041] printILog
2016-05-16 20:19:21.936 test[17888:1058041] printYLog
Method * mm = class_copyMethodList(object_getClass([[sunClasssuperclass]class]), &count); //equal to Method * mm = class_copyMethodList(object_getClass([[sunClassclass]superclass]), &count); NSLog(@"%u",count); for(int j =0; j < count; j++) { Method mt = mm[j]; SEL sel =method_getName(mt); NSString *strName = [NSString stringWithCString:sel_getName(sel)encoding:NSUTF8StringEncoding]; NSLog(@"%@",strName); }
2016-05-16 20:22:32.720 test[17930:1060301] 2
2016-05-16 20:22:32.720 test[17930:1060301] printILog
2016-05-16 20:22:32.720 test[17930:1060301] printIILog
- oc 元类 元数据
- OC:对象、类、元类
- 元数据
- 元数据
- 元数据
- 数据元
- 元数据
- 元数据
- 元数据
- 元数据
- 元数据
- 元数据
- 元数据
- 元数据
- 元数据
- 元数据
- 元数据
- 元数据
- oracle如何用sql查询某个表中所有的字段名称(列名)?
- TableLayout布局
- Spark集群安装之——Zookeeper+Kafka 安装教程
- ubuntu ssh 客户端查看服务器端图形界面
- Myeclipse项目转成Eclipse项目
- oc 元类 元数据
- 关键字自动化-方法执行
- [从头学数学] 第209节 带着计算机去高考(一)
- 小区网络利用树莓派对其他电脑实现远程开机(WOL)
- Jenkins -- 设置域账号登录错误导致无法登录
- 1)基本常用命令
- 运动跟踪之均值漂移(MeanShift)算法和Camshift算法(连续自适应的MeanShift)
- 数组——数组中最长连续序列
- python本地版wordCloud字符云生成