OC:对象、类、元类
来源:互联网 发布:双代号网络时间参数 编辑:程序博客网 时间:2024/05/18 06:09
老实讲,从Java转OC后头一回碰到元类的概念时有点懵,这篇博文算是往回看,看看oc的对象、类、元类间
参考资料
如果你是头一回知道这个概念,可以先看看别人的文章,和别人的文章等
别人的文章里有一副概念图!!
没有为什么(为什么有类和元类?)
看下结论,NSObject,Class,MetaClass都是objc_object结构体。
class和metaclass是objc_object很好证明,代码里写着class的isa是class(具体见class_getMetaClass实现),class是objc_class而objc_class集成objc_object,那么为什么NSObject是objc_object,目前我只能的从objc_isClass(id obj)接受参数id指针(代码里定义为objc_object指针),但可以调用objc_isClass(objcInstance)(传入对象实例)来略窥一二,NSObject也是objc_object。这里对于NSObject是objc_object有直接证明的望指教!
NSObject唯一的私有变量isa指向了Class, Class的isa指向了另一个Class也就是元类。
那么obj和class的区别会在哪里?
__unused BOOL objIsNotClass = object_isClass(self); __unused BOOL ClassIsCls = object_isClass([self class]); __unused BOOL MetaClassIsCls = object_isClass(objc_getMetaClass(object_getClassName([self class])));
引入<objc.runtime.h>后可自行测试,self为对象实例
答案很清晰,那么结论那里来?
进入该方法看到最后一步是判断isMetaClass,断点调试,以下是我的实验结果(稍等,哪里有代码?可参考这篇文章末尾)
看isMetaClass实现:
bool isMetaClass() { assert(this); assert(isRealized()); return data()->ro->flags & RO_META; }这里的ro就是class_ro_t结构体,看下这个结构体
struct class_ro_t { uint32_t flags; uint32_t instanceStart; uint32_t instanceSize;#ifdef __LP64__ uint32_t reserved;#endif const uint8_t * ivarLayout; const char * name; method_list_t * baseMethodList; protocol_list_t * baseProtocols; const ivar_list_t * ivars; const uint8_t * weakIvarLayout; property_list_t *baseProperties; method_list_t *baseMethods() const { return baseMethodList; }};
断点调试-》打印出class_ro_t结构体:(截的图审核完不见了,这里就贴一下数据好了)
obj的class_ro_t结构体打印数据:
flags = 128 instanceStart = 8 instanceSize = 8 reserved = 0 ivarLayout = 0x0000000000000000 <no value available> name = 0x0000000100001f4c "OCForwardMsgTest" baseMethodList = 0x0000000100002490 baseProtocols = 0x0000000000000000 ivars = 0x0000000000000000 weakIvarLayout = 0x0000000000000000 <no value available> baseProperties = 0x0000000000000000
obj的class的class_ro_t结构体其打印数据:
flags = 129 instanceStart = 40 instanceSize = 40 reserved = 0 ivarLayout = 0x0000000000000000 <no value available> name = 0x0000000100001f4c "OCForwardMsgTest" baseMethodList = 0x00000001000023e0 baseProtocols = 0x0000000000000000 ivars = 0x0000000000000000 weakIvarLayout = 0x0000000000000000 <no value available> baseProperties = 0x0000000000000000
obj的metaclass的class_ro_t结构体打印数据:
flags = 3 instanceStart = 40 instanceSize = 40 reserved = 0 ivarLayout = 0x0000000000000000 <no value available> name = 0x00000001000f39f5 "NSObject" baseMethodList = 0x00000001004a2110 baseProtocols = 0x00000001004a2870 ivars = 0x0000000000000000 weakIvarLayout = 0x0000000000000000 <no value available> baseProperties = 0x0000000000000000
简单拿结果套下公式可以知道结果,至于为什么flag会有这样的区别,挖个坑以后再看
画图
利用class_getMetaClass(cls)可以得到
class->metaclass->nsobjectMetaClass->nsobjectMetaClass 这样的路径
再结合superclass就能画出文章开头里别人的文章里的介绍图了
另:
欢迎指出问题和话题讨论
- OC:对象、类、元类
- oc 元类 元数据
- Oc类和对象
- OC类和对象
- OC 类和对象
- OC类和对象
- OC--类与对象
- OC--类和对象
- OC---类与对象
- OC--类和对象
- OC 类 和 对象
- OC-类对象
- OC类对象
- OC-类和对象
- OC 类对象
- OC 类 对象
- OC-类与对象
- 对象与元类对象
- 08关系数据库的设计
- 把BST转换为双向链表
- 10存储和文件结构
- 10存储和文件结构
- 11索引与散列
- OC:对象、类、元类
- 14事务
- Java 加密与解密
- [LeetCode]412. Fizz Buzz
- JVM内幕:Java虚拟机详解
- Python中的类(上)
- ubuntu14.04 rabbitmq安装、线上部署及允许其他ip地址访问
- 淘宝app属于hybrid app吗?
- 【POJ】Symmetric Order