美文网首页ios进阶
Objective - C 对象的本质(一) OC语言的本质及N

Objective - C 对象的本质(一) OC语言的本质及N

作者: 爱玩游戏的iOS菜鸟 | 来源:发表于2020-04-22 15:04 被阅读0次

(一)OC语言的本质

  • 其实我们编写的OC代码,底层实现都是C/C++代码
  • Objective-C的面向对象都是基于C\C++的数据结构实现的


    语言转化流程

那么,是基于什么数据结构实现的呢?结构体

(1)将OC代码转换为C++代码

xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc OC源文件 -o 输出的CPP文件

  • xcrun Xcode run简写
  • -sdk iphoneos 指定SDK 运行的OS平台
  • clang 编译器的一种
  • -arch arm64 声明架构代码(i386 、armv7 、arm64)
  • -rewrite-objc 重写objc代码
  • -o 输出
  • 如果需要链接其他框架,使用-framework参数。如-framework UIKit

示例:

xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main.cpp
(2)NSObject的本质

我们在.cpp文件中,找到这样一段代码,发现NSObject底层实现

struct NSObject_IMPL {//NSObject implementation
    Class isa;//很重要,后面会讲到
};

另外我们在OC文件中,找到NSObject头文件的定义

@interface NSObject <NSObject> {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-interface-ivars"
    Class isa  OBJC_ISA_AVAILABILITY;
#pragma clang diagnostic pop
}

通过这个我们可以侧面证明,NSObject的底层实现是通过C/C++的结构体的数据结构实现的

isa指针如果不好理解的话,isa指针可以类比数组的首元素,数组的首元素的地址也就是数组的首地址

(2)NSObject的占用的内存大小

我们继续查看isa,发现是这么定义的

typedef struct objc_class *Class;

这是一个指向结构体的指针

如下面的代码,我们通过runtime和malloc的方法得到NSObject所占用内存大小的信息,为什么会有8和16的区别呢?

#import <objc/runtime.h>
#import <malloc/malloc.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        
        NSObject *obj = [[NSObject alloc] init];
          
        //获得NSObject类的实例对象中成员变量所占内存的大小(内存对齐后)
        NSLog(@"%zd",class_getInstanceSize([obj class]));//8
        //获得obj指针所指向内存的大小
        NSLog(@"%zu",malloc_size((__bridge const void *)obj));//16
    }
    return 0;
}

查看runtime源码找到class_getInstanceSize方法

  size_t class_getInstanceSize(Class cls)
  {
    if (!cls) return 0;
    return cls->alignedInstanceSize();
  }
  //再深入查看,发现这一条解释 返回的是成员变量占用的内存大小
  // Class's ivar size rounded up to a pointer-size boundary.
  uint32_t alignedInstanceSize() const {
     return word_align(unalignedInstanceSize());
  }

而在NSObject调用alloc方法实际上allocWithZone方法,在runtime中最后调用的是_objc_rootAllocWithZone方法,我们深入查看,最后找到instanceSize方法,是指定对象内存大小的方法

NEVER_INLINE
id
_objc_rootAllocWithZone(Class cls, malloc_zone_t *zone __unused)
{
    // allocWithZone under __OBJC2__ ignores the zone parameter
    return _class_createInstanceFromZone(cls, 0, nil,
                                         OBJECT_CONSTRUCT_CALL_BADALLOC);
}

size_t instanceSize(size_t extraBytes) const {
        if (fastpath(cache.hasFastInstanceSize(extraBytes))) {
            return cache.fastInstanceSize(extraBytes);
        }

        size_t size = alignedInstanceSize() + extraBytes;
        // CF requires all objects be at least 16 bytes.
        //很重要!!!
        if (size < 16) size = 16;//如果不足16个字节,强制分配16个字节
        return size;
    }

所以也就能解释,系统给NSobject对象分配16个字节,实际使用到的只有8个字节,分别通过class_getInstanceSize函数和malloc_size函数可以知道

(3)容易混淆的两个函数
  • class_getInstanceSize
  • malloc_size
    上面用到了两个函数,很容易混淆他们之间的区别
  1. 创建一个实例对象,(内存对齐后)至少需要多少内存?
    #import <objc/runtime.h>
    class_getInstanceSize([NSObject class]);

  2. 创建一个实例对象,实际上分配了多少内存?
    #import <malloc/malloc.h>
    malloc_size((__bridge const void *)obj);

(3)窥探NSObject的内存
也可以使用LLDB指令
(4)常用的LLDB指令
常用LLDB指令 读取内存方法不同 顺序会有区别(高高低低原则)

具体窥探内存方法以及LLDB指令的使用在 Swift-七、枚举类型 可选项也有讲述

相关文章

  • OC对象的本质(上)

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

  • 总结

    主题一《OC对象的本质》=========== 1、OC的本质 Objective-C ----> C\C++ -...

  • Objective - C 对象的本质(一) OC语言的本质及N

    (一)OC语言的本质 其实我们编写的OC代码,底层实现都是C/C++代码 Objective-C的面向对象都是基于...

  • 【iOS 底层原理】OC 对象的本质

    一、OC 对象的本质 探寻OC对象的本质,我们平时编写的Objective-C代码,底层实现其实都是C\C++代码...

  • OC对象的本质(下)

    iOS | OC对象本质 | Objective-C OC对象的分类,对象的isa指针指向哪里,superClas...

  • Runtime源码编译

    Objective-C是基于c语言的封装,使C语言具有了面向对象的能力.OC的本质最终还是转换c语言来执行,而这个...

  • iOS | 底层原理分析 (一)

    一. OC对象本质 1.1 OC对象数据结构 我们平时编写的Objective-C代码,底层实现其实都是C\C++...

  • Objective-C对象的本质

    一、OC对象的本质 我们平时编写的Objective-C代码,底层实现其实都是C\C++代码 Objective-...

  • iOS底层原理总结 之-探寻OC对象的本质

    探寻OC对象的本质,我们平时编写的Objective-C代码,底层实现其实都是C\C++代码。 OC的对象结构都是...

  • OC-对象的本质

    前言 探寻OC对象的本质,我们平时编写的Objective-C代码,底层实现其实都是C\C++代码。OC的对象都是...

网友评论

    本文标题:Objective - C 对象的本质(一) OC语言的本质及N

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