美文网首页
OC中对象的本质

OC中对象的本质

作者: Eli_app | 来源:发表于2021-06-15 17:00 被阅读0次

对象在C++层面的表现

我们先准备以下代码

@interface ELPerson : NSObject



@property (nonatomic, strong) NSString *ELname;



- (void)testfunction;



@end

用如下代码把他编译成c++代码

 xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp

打开生成的.cpp文件,我们搜索一下,找到

struct ELPerson_IMPL {

    struct NSObject_IMPL NSObject_IVARS;

    NSString *_ELname;

};

我们继续搜索ELPerson_IMPL

struct NSObject_IMPL {

    Class isa;

};

他在c++层面就是这样一个结构体,里面并没有存储我们定义的方法。就是结构体指针isa

NSObjectruntime中对应的源码为

/// Represents an instance of a class.

struct objc_object {

  Class _Nonnull isa OBJC_ISA_AVAILABILITY;

};

类对象的源码应该为

struct objc_class : objc_object {

  // Class ISA;

  Class superclass;

  cache_t cache;       // formerly cache pointer and vtable

  class_data_bits_t bits;  // class_rw_t * plus custom rr/alloc flags

。。。函数

}

objc_class继承objc_object,也就继承了isa。这里也说明:对象包含类对象和实例对象。

探寻ISA的实现

我们继续探究ISA,他的源码应该为如下:(x86_64架构精简代码说明)

union isa_t {

。。。//省略

  struct {
   uintptr_t nonpointer    : 1;                     \

   uintptr_t has_assoc     : 1;                     \

   uintptr_t has_cxx_dtor   : 1;                     \

   uintptr_t shiftcls     : 44; /*MACH_VM_MAX_ADDRESS 0x7fffffe00000*/ \

   uintptr_t magic       : 6;                     \

   uintptr_t weakly_referenced : 1;                     \

   uintptr_t unused      : 1;                     \

   uintptr_t has_sidetable_rc : 1;                     \

   uintptr_t extra_rc     : 8

  }

};

nonpointer在0位,表示是否对isa指针开启指针优化。0:纯isa指针,这里面直接存储ClassMeta-Class 对象的地址(没有使用位域)1:代表优化过的,使用了位域,里面包含位域里面的这些信息(类对象地址,isa包含了类信息、对象的引用计数等),想要得到类对象元类对象,需要&上ISA_MASK(也可以使用地址平移)才能得到。

has_assoc在1位,表示关联对象标志位,0:没有,1:有。

has_cxx_dtor在2位,表示该对象是否有C++或者Objc的析构器,如果有析构函数,则需要做析构逻辑,如果没有,则可以更快的释放对象。

shiftclsx86架构中占用3~46位,表示存储类指针的值。开启指针优化的情况下,在arm64架构中占用3~35位。

magicx86架构中占用47~52位,在arm64架构中占用36~41位,用于调式器判断当前对象是真的对象还是没有初始化的空间。

weakly_referencedx86架构中占用第53位,在arm64架构中占用第42位,标志对象是否被指向或者曾经指向一个ARC的弱变量,没有弱引用的对象可以更快释放。

unusedx86架构中占用第54位,在arm64架构中占用第43位,标志对象是否正在释放内存。

has_sidetable_rcx86架构中占用第55位,在arm64架构中占用第44位,表示当对象引用计数大于10时,则需要借用该变量存储进位。

extra_rcx86架构中占用56~63位,在arm64架构中占用45~63位,当表示该对象的引用计数值时,实际上是引用计数值减1,例如:如果对象的引用计数为10,那么extra_rc9,如果引用计数大于10,则需要使用到has_sidetable_rc

我们直接测试一下shiftcls位置是否是类的信息

(lldb)x/4gx per //打印对象地址,首地址为isa

0x10065c0d0: 0x011d8001000082e5 0x0000000000000000

0x10065c0e0: 0x0000000000000000 0x0000000000000000

(lldb) p/x per.class //打印类对象地址

(Class) $8 = 0x00000001000082e0 ELPerson

(lldb)p/x 0x011d8001000082e5 >> 3 << 20 >> 17 //算法在下面说明

(long) $9 = 0x00000001000082e0 //说明对象的isa里面包含类对象的地址信息

(lldb) 

位运算图解:

image

再打印一下二进制的内存情况,方便对照,如下:

(lldb) x/1gt per0x10065c0d0: 0b0000000100011101100000000000000100000000000000001000001011100101(lldb)

相关文章

  • OC 与 Swift

    OC对象的本质(上):OC对象的底层实现原理OC对象的本质(中):OC对象的种类OC对象的本质(下):详解isa&...

  • OC对象的本质(中)—— OC对象的种类

    OC对象的本质(上):OC对象的底层实现原理OC对象的本质(中):OC对象的种类OC对象的本质(下):详解isa&...

  • OC对象的本质(下)—— 详解isa&supercl

    OC对象的本质(上):OC对象的底层实现原理OC对象的本质(中):OC对象的种类OC对象的本质(下):详解isa&...

  • OC对象的本质(上)

    iOS | OC对象本质 | Objective-C 什么是OC语言,OC对象、类的本质是什么,OC对象的内存布局...

  • OC中对象的本质

    对象在C++层面的表现 我们先准备以下代码 用如下代码把他编译成c++代码 打开生成的.cpp文件,我们搜索一下,...

  • block 笔记

    block本质是OC对象(封装了函数调用以及调用环境的OC对象) 本质

  • Runtime:OC对象、类、元类的本质

    零、Runtime是什么一、OC对象的本质二、OC类的本质三、OC元类的本质四、Runtime关于对象、类、元类的...

  • 内存管理

    1.只有OC对象才需要进行内存管理的本质原因 --1.OC对象存放于堆中 --2.非OC对象存在栈中(栈内存会被系...

  • Ios面试复习--MRC内存管理

    1.只有OC对象才需要进行内存管理的本质原因 --1.OC对象存放于堆中 --2.非OC对象存在栈中(栈内存会被系...

  • NULL 、 nil 、 Nil 、NSNull

    OC中对象的本质: 执行OC代码Person *p = [[Person alloc] init];内部过程:Pe...

网友评论

      本文标题:OC中对象的本质

      本文链接:https://www.haomeiwen.com/subject/wbgzeltx.html