iOS底层原理03 - 对象的本质与isa

上一篇: 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时,会将classisa进行绑定,类的信息会被存储在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结构体中包含了哪些信息,后面再进行研究。

你可能感兴趣的:(iOS底层原理03 - 对象的本质与isa)