objective c下的对象模型
2015-12-30 16:55
218 查看
前言
通过clang将objective c代码翻译成cpp代码,阅读代码的实现去理解objc中对象模型。objective c代码
#import <Foundation/Foundation.h> @interface TestA : NSObject { int age; NSString *name; } - (void)instanceMethod; + (void)classMethod; @end @implementation TestA - (void)instanceMethod { NSLog(@"instance method~"); } + (void)classMethod { NSLog(@"class method~"); } @end
代码块中含有类方法以及普通的方法。
clang翻译objective c代码块
clang -rewrite-objc TestA.m
Objective c的对象模型
先介绍一下objective c runtime下id以及class类型。struct objc_class { struct objc_class *isa; ..... }; struct objc_object { struct objc_class *isa; }; typedef struct objc_class *Class; //类 (class object) typedef struct objc_object *id; //对象 (instance of class)
struct objc_object * id代表一个class instance的对象,在objc_object结构体中有一个成员isa,这个变量指向id对象所属class。
struct objc_class *Class代表一个类对象,在objc_class结构体中有一个成员isa,这个变量指向类对象的meta-class。
注意这两个结构体中的isa指向的内容是不同的。
通过clang的命令,已经将TestA.m文件翻译成TestA.cpp代码。
struct _class_t OBJC_CLASS_$_TestA __attribute__ ((used, section ("__DATA,__objc_data"))) = { 0, // &OBJC_METACLASS_$_TestA, 0, // &OBJC_CLASS_$_NSObject, 0, // (void *)&_objc_empty_cache, 0, // unused, was (void *)&_objc_empty_vtable, &_OBJC_CLASS_RO_$_TestA, }; static struct _class_ro_t _OBJC_CLASS_RO_$_TestA __attribute__ ((used, section ("__DATA,__objc_const"))) = { 0, __OFFSETOFIVAR__(struct TestA, age), sizeof(struct TestA_IMPL), (unsigned int)0, 0, "TestA", (const struct _method_list_t *)&_OBJC_$_INSTANCE_METHODS_TestA, 0, (const struct _ivar_list_t *)&_OBJC_$_INSTANCE_VARIABLES_TestA, 0, 0, };
这里 struct class_t OBJC_CLASS$_TestA 对应的就是前面介绍的 struct objc_class 结构体,我们可以观察struct objc_class 结构体中包含的信息。这里我们转译一下此结构体方便阅读。
struct objc_class { Class isa; Class super_class OBJC2_UNAVAILABLE; const char *name OBJC2_UNAVAILABLE; long version OBJC2_UNAVAILABLE; long info OBJC2_UNAVAILABLE; long instance_size OBJC2_UNAVAILABLE; struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; struct objc_method_list **methodLists OBJC2_UNAVAILABLE; struct objc_cache *cache OBJC2_UNAVAILABLE; struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; } ;
对比上下两个结构体,可以看出整个struct objc_class所包含的信息。
这里主要介绍几个重要的信息。
变量 | 含义 |
---|---|
isa | class的meta-class, TestA metaclass是OBJC_METACLASS_$_TestA |
super_class | class的superclass, TestA superclass是OBJC_CLASS_$_NSObject |
const char *name | 类名, 在结构体中OBJC_CLASS_RO$_TestA中赋值为”TestA” |
struct objc_ivar_list *ivars | 成员变量列表 |
struct objc_method_list **methodLists | 普通函数表(即非类函数) |
struct objc_cache *cache | 最近使用函数列表,objc_msgsend过程中查找函数地址时使用缓存表 |
初始化
static void OBJC_CLASS_SETUP_$_TestA(void ) { OBJC_METACLASS_$_TestA.isa = & 8fc7 amp;OBJC_METACLASS_$_NSObject; OBJC_METACLASS_$_TestA.superclass = &OBJC_METACLASS_$_NSObject; OBJC_METACLASS_$_TestA.cache = &_objc_empty_cache; OBJC_CLASS_$_TestA.isa = &OBJC_METACLASS_$_TestA; OBJC_CLASS_$_TestA.superclass = &OBJC_CLASS_$_NSObject; OBJC_CLASS_$_TestA.cache = &_objc_empty_cache; }
结合静态函数OBJC_CLASS_SETUP_$$_TestA(void)
可以看到OBJC_METACLASS_$_TestA.isa被赋值给了NSObject的meta-class, OBJC_METACLASS_$_TestA.superclass也被赋值给了OBJC_METACLASS_$_NSObject
函数调用的区别
调用方法一:TestA * instance = [[TestA alloc] init]; [instance instanceMethod];
通过上述讲解,整个过程首先会找到TestA * instance对应的struct objc_object结构体,通过struct objc_object中的isa指针,找到TestA的类对象,然后在TestA类对象的结构体struct objc_class中的method list查找instanceMethod函数。
调用方法二:
[TestA classMethod];
类函数的调用过程:这里会直接找到TestA类对象的结构体struct objc_class中的isa指针,而struct objc_class中的isa指向的是TestA的meta-class即OBJC_METACLASS_$_TestA,再通过查找meta-class的存储的类函数,实现函数的调用。
总结:通过上述讲解,大家可以看出普通的函数地址存储在struct objc_class结构体中methodLists中,而类方法的地址则存储在类对象对应的meta-class中。
让我们继续看meta-class结构体。
meta-class结构体
meta-class结构体的定义extern "C" __declspec(dllexport) struct _class_t OBJC_METACLASS_$_TestA __attribute__ ((used, section ("__DATA,__objc_data"))) = { 0, // &OBJC_METACLASS_$_NSObject, 0, // &OBJC_METACLASS_$_NSObject, 0, // (void *)&_objc_empty_cache, 0, // unused, was (void *)&_objc_empty_vtable, &_OBJC_METACLASS_RO_$_TestA, };
meta-class结构体的定义和struct objc_class完全相同。
整体结构
希望通过本文,可以加深你对objective c的对象模型的理解,如有错误,请提出,我会及时改正,大家共同学习。
相关文章推荐
- ES6学习——新的语法:对象解构(Object Destructuring)
- Objective-C学习日志1
- Android属性动画完全解析(中),ValueAnimator和ObjectAnimator的高级用法
- objectiveC【语法】修饰符 static extern const 详解
- Objective-C中的单例模式(singleton)
- Effective objective-C 2.0总结归纳
- Objective-C学习篇第十弹:NSDate详解
- Objective-c语言_面向对象(便利初始化函数,构造器和多态的结合)
- ASP.NET MVC - Passing anonymous objects to MVC views and accessing them using dynamic
- Ownership of Container Object
- Objective-c语言_面向对象(多态)2
- [1]姥爷幽默谈Objective-C(Objective-C起源,对象,类,方法)
- NSObject易误解处
- Object源码后记
- Objective-c与js相互调用
- JSONArray.fromObject()注入处理日期Date格式
- SQL Server系统表sysobjects介绍与使用
- IOS开发系列----Objective-c的内存管理
- #Objective - C - UI-design - 第一天 -UIKit框架-UIKit-UIView
- java中Object源码分析