上一篇: iOS底层原理02 - 对象malloc流程分析
下一篇: iOS底层原理04 - 类的结构
要研究什么是对象,首先我们先创建一个对象:
@interface ViewController : NSObject
@end
@implementation ViewController
@end
通过Clang
命令变成成.cpp文件来查看:
clang -rewrite-objc ViewController.m -o ViewController.cpp
// 活报错找不到UIKit,则使用命令指定sdk路径
clang -rewrite-objc -fobjc-arc -fobjc-runtime=ios-14.5.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator14.5.sdk ViewController.m
对象的结构
#ifndef _REWRITER_typedef_ViewController
#define _REWRITER_typedef_ViewController
typedef struct objc_object ViewController;
typedef struct {} _objc_exc_ViewController;
#endif
struct ViewController_IMPL {
struct UIViewController_IMPL UIViewController_IVARS;
};
很明显看出,ViewController
对象其实就是一个结构体!他的第一个属性是UIViewController_IMPL
类型的结构体,UIViewController_IMPL又是最终伪继承
自结构体NSObject_IMPL
:
struct NSObject_IMPL {
__unsafe_unretained Class isa;
};
所以对象的第一个属性其实是Class类型的isa,当中存储着类中的各种信息。
这里的isa
进行了类型转换,所以对外展示为Class
类型。
isa是个isa_t
类型的联合体,他的初始化过程在iOS底层原理01 - 对象alloc、init、new源码分析中提到过,在initIsa
时,会将class
和isa
进行绑定,类的信息会被存储在shiftcls
中。
- 我们回过头去看objc源码中的
objc_object::initIsa
方法,
inline void
objc_object::initIsa(Class cls, bool nonpointer, UNUSED_WITHOUT_INDEXED_ISA_AND_DTOR_BIT bool hasCxxDtor)
{
......
isa_t newisa(0);
if (!nonpointer) {
newisa.setClass(cls, this);
} else {
......
newisa.bits = ISA_INDEX_MAGIC_VALUE;
newisa.has_cxx_dtor = hasCxxDtor;
newisa.indexcls = (uintptr_t)cls->classArrayIndex();
#else
newisa.bits = ISA_MAGIC_VALUE;
# if ISA_HAS_CXX_DTOR_BIT
newisa.has_cxx_dtor = hasCxxDtor;
# endif
newisa.setClass(cls, this);
#endif
newisa.extra_rc = 1;
}
// 将newisa绑定到this也就是当前对象的isa中
isa = newisa;
}
在进行完setClass
后,newisa
联合体中已经包含了当前class的信息,但this
也就是当前对象中的信息还是空的:
但执行完最后一句 isa = newisa;
后,this
即当前person对象结构体objc_object
中的isa
就已经被赋上值了,也就完成了isa和class的绑定。
至于Class结构体中包含了哪些信息,后面再进行研究。