iOS实例、类、元类
从源码看本质
源代码:
@interface XKPerson ()@property (copy, nonatomic) NSString *name;@end@implementation XKPerson+ (instancetype)personWithName:(NSString *)name {XKPerson *p = [XKPerson new];p.name = name;return p;
}
转化成cpp,整理相关代码:
// 对象信息的实际存储者
struct _class_ro_t {unsigned int flags;unsigned int instanceStart;unsigned int instanceSize;const unsigned char *ivarLayout;const char *name;const struct _method_list_t *baseMethods;const struct _objc_protocol_list *baseProtocols;const struct _ivar_list_t *ivars;const unsigned char *weakIvarLayout;const struct _prop_list_t *properties;
};// 定义了XKPerson的元类
static struct _class_ro_t _OBJC_METACLASS_RO_$_XKPerson = {1, sizeof(struct _class_t), sizeof(struct _class_t), 0, "XKPerson",(const struct _method_list_t *)&_OBJC_$_CLASS_METHODS_XKPerson,0, 0, 0, 0,
};// 定义了XKPerson的类对象
static struct _class_ro_t _OBJC_CLASS_RO_$_XKPerson = {0, __OFFSETOFIVAR__(struct XKPerson, _name), sizeof(struct XKPerson_IMPL), 0, "XKPerson",(const struct _method_list_t *)&_OBJC_$_INSTANCE_METHODS_XKPerson,0, (const struct _ivar_list_t *)&_OBJC_$_INSTANCE_VARIABLES_XKPerson,0, 0,
};// 对象的管理者
struct _class_t {// 传说中的isastruct _class_t *isa;// 传说中的superclassstruct _class_t *superclass;// 缓存相关void *cache;// 暂不使用void *vtable;// 对象信息的实际保存者struct _class_ro_t *ro;
};struct _class_t OBJC_METACLASS_$_NSObject;// 是_class_t,用于管理_XKPerson元类
struct _class_t OBJC_METACLASS_$_XKPerson = {0, // &OBJC_METACLASS_$_NSObject,0, // &OBJC_METACLASS_$_NSObject,0, // (void *)&_objc_empty_cache,0, // unused, was (void *)&_objc_empty_vtable,&_OBJC_METACLASS_RO_$_XKPerson,
};struct _class_t OBJC_CLASS_$_NSObject;// 是_class_t,管理XKPerson的类对象
struct _class_t OBJC_CLASS_$_XKPerson __attribute__ ((used, section ("__DATA,__objc_data"))) = {0, // &OBJC_METACLASS_$_XKPerson,0, // &OBJC_CLASS_$_NSObject,0, // (void *)&_objc_empty_cache,0, // unused, was (void *)&_objc_empty_vtable,&_OBJC_CLASS_RO_$_XKPerson,
};// 真正使用的是_class_t,需要对齐进行初始化
static void OBJC_CLASS_SETUP_$_XKPerson(void ) {// 所有元类的isa指向根源类,也就是metaNSObject// metaNSObject的isa指向跟类对象,也就是classNSObjectOBJC_METACLASS_$_XKPerson.isa = &OBJC_METACLASS_$_NSObject;// 元类的superclass指向父元类OBJC_METACLASS_$_XKPerson.superclass = &OBJC_METACLASS_$_NSObject;OBJC_METACLASS_$_XKPerson.cache = &_objc_empty_cache;// 类对象的isa指向元类OBJC_CLASS_$_XKPerson.isa = &OBJC_METACLASS_$_XKPerson;// 类对象的superclass指向父[类对象]// 跟类对象(classNSObject)指向为nil,触发消息转发机制OBJC_CLASS_$_XKPerson.superclass = &OBJC_CLASS_$_NSObject;OBJC_CLASS_$_XKPerson.cache = &_objc_empty_cache;
}
为什么 [[obj class] class] 方法获取不到元类
实例对象、类对象、元类的获取代码如下:
NSObject *obj1 = [[NSObject alloc] init];NSObject *obj2 = [[NSObject alloc] init];NSObject *obj3 = [[NSObject alloc] init];NSLog(@"instance address:%p %p %p",obj1, obj2, obj3);NSLog(@"class address: %p %p %p",[obj1 class], [obj2 class], [obj3 class]);NSLog(@"meta class address:%p %p %p",object_getClass([obj1 class]), object_getClass([obj2 class]), object_getClass([obj3 class]));NSLog(@"error meta class address:%p %p %p",[[obj1 class] class], [[obj2 class] class], [[obj3 class] class]);
打印结果:
2020-11-04 09:05:26.264248+0800 XKObjTest[82779:33963605] instance address:0x10285f9a0 0x10285ffb0 0x10285e3d0
2020-11-04 09:05:26.265428+0800 XKObjTest[82779:33963605] class address: 0x7fff9b7d5140 0x7fff9b7d5140 0x7fff9b7d5140
2020-11-04 09:05:26.265520+0800 XKObjTest[82779:33963605] meta class address:0x7fff9b7d50f0 0x7fff9b7d50f0 0x7fff9b7d50f0
2020-11-04 09:05:26.265600+0800 XKObjTest[82779:33963605] error meta class address:0x7fff9b7d5140 0x7fff9b7d5140 0x7fff9b7d5140
Program ended with exit code: 0
我们都知道[[instance class] class]
这样是无法获取到元类的,那原因是什么呢?查找 objc 源码得到 class 方法的源码:
+ (Class)class {return self;
}- (Class)class {return object_getClass(self);
}
如上图所示,虽然 class 方法本质是调用 object_getClass,但是类方法 class 确是直接返回自己,也就是类对象,所以类对象无论调用多少次 class 方法,返回的都是类对象自己。
而 object_getClass 的源码如下:
Class object_getClass(id obj)
{if (obj) return obj->getIsa();else return Nil;
}
这个方法直接返回的是 isa 指针的指向,所以可以获取到元类;
http://www.taodudu.cc/news/show-1912777.html
相关文章:
- id和instancetype
- Advanced Graphics and Animations for iOS Apps
- ivar和property
- bound、frame、position、anchorPoint
- Java、OC、C/C++中的null
- iOS:Tagged Pointer
- sqlite3源码调试
- 红黑树、B树、B+树各自适用的场景
- 动态库的隐式链接和显示链接
- iOS:懒加载符号绑定流程
- 汇编:call和jmp
- code review的一些思考
- iOS:fishhook原理分析
- mach-O文件结构分析
- 设备唯一标志的解决方案
- iOS:主流启动优化方案浅析
- iOS:segment对齐原则
- HTTP缓存机制及其在iOS中的应用
- iOS:SideTable
- iOS:isa指针
- iOS底层:PAGEZERO的作用
- iOS图形学(三):屏幕成像原理
- iOS图形学(四):iOS中的绘图框架
- Java基础(一):简介和基础数据类型
- Java基础(二):面向对象
- Java:常量池
- Java基础(三):常用对象
- Java基础(四):异常处理
- Java基础(五):多线程
- Android:权限处理
iOS实例、类、元类相关推荐
- php元类,iOS中类、元类、isa详解
本文是来自@FlyOceanFish的投稿 类相信大家都知道是什么,如果看过runtime的源码或者看过相关的文章对isa肯定也不陌生,不过元类(meta class)大家可能就比较陌生了.不过大家也 ...
- Python元类和新型类-对象是类的实例,那类又是谁的实例?
文章目录 元类 类工厂 初始元类 元类属性 元类作用 面向方面和元类 小结 新型类 新型类VS传统类 静态方法和类方法 特定方法 特定属性 super()方法 小结 元类 既然对象是以类为模板生成的, ...
- 深入理解 python 元类
一.什么的元类 # 思考: # Python 中对象是由实例化类得来的,那么类又是怎么得到的呢? # 疑问: # python 中一切皆对象,那么类是否也是对象?如果是,那么它又是那个类实例化而来的呢 ...
- [转]深刻理解Python中的元类(metaclass)
类也是对象 在理解元类之前,你需要先掌握Python中的类.Python中类的概念借鉴于Smalltalk,这显得有些奇特.在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段.在Pytho ...
- Python中的元类是什么?
元类是什么,我们将它们用于什么? #1楼 请注意,此答案适用于2008年编写的Python 2.x,元类在3.x中略有不同. 元类是使"类"工作的秘诀. 新样式对象的默认元类称为& ...
- Python中的元类(metaclass)
类也是对象 在理解元类之前,你需要先掌握Python中的类.Python中类的概念借鉴于Smalltalk,这显得有些奇特.在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段.在Pytho ...
- 深刻理解Python中的元类(metaclass)以及元类实现单例模式
在看一些框架源代码的过程中碰到很多元类的实例,看起来很吃力很晦涩:在看python cookbook中关于元类创建单例模式的那一节有些疑惑.因此花了几天时间研究下元类这个概念.通过学习元类,我对pyt ...
- python元类简述
面向对象编程 python 是一门按照面向对象思维设计的一门编程语言,而理解面向对象的语言关键在于一句话,"一切皆对象",函数是一个对象,一个实例是对象,一个类也是对象.如果对象被 ...
- python可以实现什么黑科技_Python黑科技之元类
Python中的类 在理解元类之前,你需要了解Python中的类.Python中的类借鉴自Smalltalk. 在大多数编程语言中,类只是描述对象生成方式的一段代码,在Python里面看起来也是这样. ...
- 编写python程序、创建名为class的数据库_Python中的元类(metaclass)以及元类实现单例模式...
一.理解类也是对象 在理解元类之前,你需要先掌握Python中的类.Python中类的概念借鉴于Smalltalk,这显得有些奇特.在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段.在P ...
最新文章
- 计算机组成原理——概述3
- 在mysql中会话变量前面的字符是什么_在MySQL中仅使用会话变量仅对字符的首次出现执行搜索/替换...
- 全球规模最大的全浸没式液冷数据中心落户杭州余杭
- jar包直接拷贝到WEB-INF/lib下和以userLibrary引入的区别
- 别再搜集面经啦!小夕教你斩下NLP算法岗offer!
- C#中的文件流和文本流
- WAS生成的文件:javacore.***.txt 、heapdump.***.phd、core.***.dmp、Snap.***.trc
- Swift学习笔记(10)--枚举
- linux命令行界面如何安装图形化界面
- Mysql函数group_concat、find_in_set进行数据库字段值翻译
- js:苹果手机页面返回,数据不刷新问题
- 单细胞测序在免疫治疗研究中的应用
- POM 标签大全详解
- 微信小程序上传图片到服务器(java后台以及使用springmvc)
- 浏览器主页被劫持篡改了怎么办
- java实现汉字判断+中文符号判断
- 51单片机点亮LED灯以及实现2盏LED灯的交替闪烁
- 【转】互联网产品经理常用软件及工作平台
- VOCBENCH声码器评价基准
- USACO 3.2 Sweet Butter 香甜的黄油