isa结构分析

2020-09-13  本文已影响0人  _涼城
什么是对象?

为了了解Objective-C类在底层会编译成什么,我们先新建一个类DebugPerson

测试类DebugPerson
@interface DebugPerson : NSObject
@property (nonatomic, copy) NSString *name;
@end

@implementation DebugPerson
@end
利用clang编译main.m文件

Clang是⼀个由Apple主导编写,基于LLVM的C/C++/Objective-C编译器。源代码发布于BSD协议下。Clang将⽀持其普通lambda表达式、返回类型的简化处理以及更好的处理constexpr关键字。

clang -rewrite-objc main.m -o main.cpp
编译结果

打开main.cpp后,搜索DebugPerson关键字,会发现类已经被编译成结构体DebugPerson_IMPL,其伪继承于NSObject_IMPLstruct NSObject_IMPL NSObject_IVARS等同于isa

得出结果 对象的本质其实就是一个结构体。

#ifndef _REWRITER_typedef_DebugPerson
#define _REWRITER_typedef_DebugPerson
typedef struct objc_object DebugPerson;
typedef struct {} _objc_exc_DebugPerson;
#endif

extern "C" unsigned long OBJC_IVAR_$_DebugPerson$_name;
struct DebugPerson_IMPL {
    struct NSObject_IMPL NSObject_IVARS;
    NSString *_name;
};

以及属性变量NSString *_name,和settergetter方法。

static NSString * _I_DebugPerson_name(DebugPerson * self, SEL _cmd) { 
    return (*(NSString **)((char *)self + OBJC_IVAR_$_DebugPerson$_name)); 
}
extern "C" __declspec(dllimport) void objc_setProperty (id, SEL, long, id, bool, bool);

static void _I_DebugPerson_setName_(DebugPerson * self, SEL _cmd, NSString *name) { 
     objc_setProperty (self, _cmd, __OFFSETOFIVAR__(struct DebugPerson, _name), (id)name, 0, 1); 
}
objc_setProperty
isa的结构信息
联合体

  联合体也是由不同的数据类型组成,但其变量是互斥的,所有的成员共占一段内存。而且共用体采用了内存覆盖技术同一时刻只能保存一个成员的值,如果对新的成员赋值,就会将原来成员的值覆盖掉。

isa_t

isa_t类型使用联合体通过char + 位域(即二进制中每一位均可表示不同的信息)进行内存优化。

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的存储情况如图所示

isa64情况.jpeg
上一篇下一篇

猜你喜欢

热点阅读