iOS底层学习-day-1

前言-OC语法篇

我是一名iOS开发者, iOS底层 菜鸟的进阶之路30天。

问题

一个NSObject对象占用多少内存?

  • 系统分配了16个字节给NSObject对象(通过malloc_size函数获得)
  • 但NSObject对象内部只使用了8个字节的空间(64bit环境下,可以通过class_getInstanceSize函数获得)

Objective-C的本质

  • LLVM指令例子
    • clang -rewrite-objc main.m -o main.cpp 生成c++文件
    • xcrun -sdk iphones clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp
    • ps:
    • // 什么平台的代码
      // 不同平台支持的代码肯定是不一样
      // Windows、mac、iOS
      // 模拟器(i386)、32bit(armv7)、64bit(arm64)
struct NSObject_IMPL {
    Class isa; // 8个字节
};
  • 一个NSObject的所占大小
    在这里插入图片描述
    在这里插入图片描述
  • 为什么,因为分配了16个字节给他,但是实际只是用到了8个字节,8个字节用来放isa指针
NSObejct *stu = [[NSObejct alloc] init];

00000000			// isa占用的大小为8个字节
0000000000000000

// 获得NSObject 实例对象 的 成员(ivar)变量 所占用的大小 >> 8
 NSLog(@"%zd", class_getInstanceSize([NSObject class]));
        
// 获得obj指针所指向内存的大小 >> 16。   coreFoundation中规定的
// malloc 分配内存  malloc_size(const void *ptr)
NSLog(@"%zd", malloc_size((__bridge const void *)obj));
  • LLDB编译器的指令
  • memory read 0x01230031 简写x ,x/ 3xg
  • memory write 0x01230031 9 //重写
  • 内存例子的说明
  • 例子1
    在这里插入图片描述
struct NSObject_IMPL {
    Class isa;
};

struct Student_IMPL {
    struct NSObject_IMPL NSObject_IVARS;
    int _no;
    int _age;
};
struct Student_IMPL {
    Class isa;  //父类的isa指针,8个字节
    int _no;    //4个字节
    int _age;   //4个字节
};

Student *stu = [[Student alloc] init];
stu->_no = 4;
stu->_age = 5;
        
NSLog(@"%zd", class_getInstanceSize([Student class]));
NSLog(@"%zd", malloc_size((__bridge const void *)stu));
        
        
struct Student_IMPL *stuImpl = (__bridge struct Student_IMPL *)stu;//4
NSLog(@"no is %d, age is %d", stuImpl->_no, stuImpl->_age);//5
  • 例子2
    在这里插入图片描述
struct NSObject_IMPL {
    Class isa;
};

struct Person_IMPL {
    struct NSObject_IMPL NSObject_IVARS; // 8
    int _age; // 4
}; // 16 内存对齐:结构体的大小必须是最大成员大小的倍数

struct Student_IMPL {
    struct Person_IMPL Person_IVARS; // 16
    int _no; // 4
}; // 16
  • 例子3
#import <malloc/malloc.h>
struct MJPerson_IMPL {
    struct NSObject_IMPL NSObject_IVARS;
    int _age;
    int _height;
    int _no;
}; // 计算结构体大小,内存对齐,24

MJPerson *p = [[MJPerson alloc] init];
        
NSLog(@"%zd", sizeof(struct MJPerson_IMPL)); // 24
        
NSLog(@"%zd %zd",
              class_getInstanceSize([MJPerson class]), // 24 //sizeof是一个宏运算符 == class_getInstanceSize是一个函数 返回这个对象正真需要的存储空间
              malloc_size((__bridge const void *)(p))); // 32 //malloc_size 指针指向的空间,返回的是实际分配的
其实是32个内容因为malloc
  • #deifne NANO_MAX_SIZE 256 // bullect_size{16,32,48,64}
  • 所以为什么是32,是因为苹果也做了一次内存对齐,所以给的是16的倍数,让CPU访问的速度快一点,遵循苹果的访问规则

两个容易混淆的函数

  • class_getInstanceSize
//创建一个实例对象,至少需要多少内存?
#import <objc/runtime.h>
class_getInstanceSize([NSObject class]);
  • malloc_size
//创建一个实例对象,实际上分配了多少内存?
#import <malloc/malloc.h>
malloc_size((__bridge const void *)obj);
发布了12 篇原创文章 · 获赞 0 · 访问量 123

猜你喜欢

转载自blog.csdn.net/weixin_41732253/article/details/103686734