手撕iOS底层07 -- What is object?

554 阅读3分钟

手撕iOS底层07 -- What is object?

前几章深入分析了对象的创建以及对象占用内存大小,本章总结下什么是对象?即对象的本质!!!


0x00 -- Clang介绍

参考官网

Clang就是LLVM项目中的一个c家族(C, C++, Objective C/C++, OpenCL, CUDA, and RenderScript)前端编译器,与GCC一样,有编译器的功能。 当然也有其它的特性, 可以去参考官网了解。

主要用于底层编译,将一些oc文件输出成cpp文件,main.m ---> main.cpp;为了更好的观底层的一些结构与实现的逻辑, 方便开发者了解底层。


//1、将 main.m 编译成 main.cpp
clang -rewrite-objc main.m -o main.cpp

//2、将 ViewController.m 编译成  ViewController.cpp
clang -rewrite-objc -fobjc-arc -fobjc-runtime=ios-13.0.0 -isysroot / /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator13.7.sdk ViewController.m

//以下两种方式是通过指定架构模式的命令行,使用xcode工具 xcrun
//3、模拟器文件编译
- xcrun -sdk iphonesimulator clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp 

//4、真机文件编译
- xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main- arm64.cpp 

注意 ⚠️ 因为我们要研究的是iOS架构下的对象,所以最好生成的支持iOSc++代码,指定平台架构不建议直接转为c++文件, 最好指定架构。 比如模拟器的i386架构或者真机的arm架构,如xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc oc源文件 -o 输出的cpp文件


0x01 -- OC对象的本质

OC对象的本质说白了就是了解对象底层使用的什么语言什么数据结构去存储这个对象,比如oc 本身是从c/c++演变过来,所以底层的开发语言也是c/c++;那使用的是c/c++什么数据结构去实现的这个对象, 数据结构有队列链表,等,那对象的底层就是使用struct结构体来实现的 。

flow.png

main.m文件

@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@end

@implementation Person
@end

main.cpp文件,通过clang -rewrite-objc main.m -o main.cpp将编译出来的main.cpp文件打开后,

//NSObject的定义
@interface NSObject <NSObject> {
    Class isa  OBJC_ISA_AVAILABILITY;
}
// NSObject底层编译
struct NSObject_IMPL {
	Class isa;
};

struct Person_IMPL {
	struct NSObject_IMPL NSObject_IVARS; // isa
	NSString *_name;
};

Person类在底层编译成一个结构体Person_IMPL,第一个成员变量struct NSObject_IMPL NSObject_IVARS,相当于NSObjectisa。底层使用这种伪继承的方式;继承了父类NSObject的成员isa

0x02 -- NSObject的isa为什么是class

在前边的分析中initInstanceIsa中, 初始化isa的类型是一个union isa_t ,即一个联合体的类型。

union isa_t {
    isa_t() { }
    isa_t(uintptr_t value) : bits(value) { }

    Class cls;
    uintptr_t bits;
#if defined(ISA_BITFIELD)
    struct {
        ISA_BITFIELD;  // defined in isa.h 这里是一些位域信息
    };
#endif
};

isa = isa_t((uintptr_t)cls);

为什么在上边的代码中, NSObjectisaClass类型,

  • 第一是对外展示为Class类型 ,从而对外反馈的是类信息。为了让开发人员更加明确。
  • 第二是在 Class ISA();的时候,返回isa的时候,做了Class类型强转
inline Class 
objc_object::ISA() 
{
    ASSERT(!isTaggedPointer()); 
#if SUPPORT_INDEXED_ISA
    if (isa.nonpointer) {
        uintptr_t slot = isa.indexcls;
        return classForIndex((unsigned)slot);
    }
    return (Class)isa.bits;
#else
    return (Class)(isa.bits & ISA_MASK); // 强转成为Class
#endif
}

总结

  • OC对象本质就是结构体
  • 每个一个自定义的类中的isa是继承父类的,直至到继承自NSObjectisa

欢迎大佬留言指正😄,码字不易,觉得好给个赞👍 有任何表达或者理解失误请留言交流;共同进步;