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




Object-C的对象模型图

    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



1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 裤子上有蜡烛油怎么办 蜡烛滴在地板上怎么办 我用面膜过敏了怎么办 敷面膜过敏肿了怎么办 贴面膜脸过敏了怎么办 隐形船袜总是掉怎么办 车钥匙没电了怎么办 水坐垫干了结晶怎么办 冰垫里面有颗粒怎么办 车上的脚垫丢了怎么办 朔钢窗锁不好使怎么办 8个月孕妇咳嗽怎么办 孕妇7个月咳嗽怎么办 孕妇6个月喉咙痒怎么办 怀孕了咳嗽的厉害怎么办 买衣服眼光太差怎么办 我买衣服没主见怎么办 海澜之家皮带长怎么办 针织衫袖口松了怎么办 宝宝裤子腰大了怎么办 两岁了头发稀少怎么办 孩子抵抗力差爱生病怎么办 三岁宝宝总生病怎么办 冬天穿伴娘服冷怎么办 白衬衣粘了黑毛怎么办 黄衣服钻进黑毛怎么办 单位没给上社保怎么办 轮毂中心孔大了怎么办 钻戒大了怎么办小窍门 shift加f4没反应怎么办 多洗联系不上怎么办 弹力靴筒往下掉怎么办 子宫内膜厚月经停不了怎么办 雪纺衣服有静电怎么办 阿胶糕熬的稀了怎么办 感冒吃了阿胶糕怎么办 身上起湿疹很痒怎么办 身上起小疹子痒怎么办 吊带裙带子断了怎么办 裙子洗完缩水了怎么办 衬衫洗后缩水了怎么办