CC的博客

  • 首页
  • iOS
  • Android
  • React-Native
  • 读书杂谈
  • About
CC
记录美好生活
  1. 首页
  2. 技术编程
  3. iOS
  4. 正文

NSObject本质--在内存中的大小

2021/03/22

OC的代码基于C/C++ 实现的,所以我们可以将OC代码转换成C++ 代码查看NSObject在C++ 中的实现。

转换命令:

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

xcrun: xcode commendline run

参数sdk 指定iphoneos系统

clang 编译器

参数arch指定arm64 CPU架构版本

rewrite-objc 重写OC的代码

参数o 指定生成的文件名,不指定则默认和原文件同名

NSObject

查看生成的cpp文件,发现NSObject对象的结构体
定义如下:

struct NSObject_IMPL {
    Class isa;
};

分析:isa为指针,指针类型(64位系统中)占8字节。
NSObject类结构体需要8字节内存,由于runtime系统设计的限制--初始化对象最少16字节,所以NSObject结构体实际需要占用16字节。

查看源码中的定义

size_t instanceSize(size_t extraBytes) {
    size_t size = alignedInstanceSize() + extraBytes;
    // CF requires all objects be at least 16 bytes.
    if (size < 16) size = 16;
    return size;
}

自定义类

@interface Person : NSObject
{
    @public
    double _weight;
    int _age;
}

@end

@implementation Person

@end

struct Person_IMPL {
    struct NSObject_IMPL NSObject_IVARS;//Class isa;
    double _weight;
    int _age;
};

分析:isa为指针,指针类型(64位系统中)占8字节,int类型占4字节,double类型指针占8字节。
所以person类结构体需要20字节内存,由于结构需要进行字节对齐(以最大成员变量的内存数为单位,此处单位为8字节),所以person结构体实际需要占用24字节。

验证方法

1、class_getInstanceSize函数获取成员变量大小
malloc_size获取对象分配的内存(内存对齐的缘故,16的倍数,所以person实例对象实际分配了32字节)

NSLog(@"%zu",class_getInstanceSize([Person class]));

Person *p = [[Person alloc] init];

NSLog(@"%zd",malloc_size((__bridge void *)p));

2、转换成结构体验证

struct Person_IMPL {
    Class isa;
    double _weight;
    int _age;
};


Person *p = [[Person alloc] init];
p->_age = 1;
p->_weight = 2;
struct Person_IMPL *s = (__bridge struct Person_IMPL *)p;

NSLog(@"%d  -- %f",s->_age,s->_weight);

3、查看内存验证

Xcode中打断点,触发断点,查看person实例对象的内存地址,然后Debug-->Debug WorkFlow-->View Memory,输入实例对象的内存地址

例如

F9 81 00 00 01 80 1D 00     //isa指针地址
00 00 00 00 00 00 00 40     //weight
01 00 00 00 00 00 00 00     //age
00 00 00 00 00 00 00 00 
2D 5B 4E 53....//其他

更复杂的情况

@interface Person : NSObject

@property (nonatomic,assign) double weight;//8

@property (nonatomic,assign) long weight1;//8

@property (nonatomic,assign) float weight2; //4

@property (nonatomic,copy) NSString *name;//8

@property (nonatomic,assign) int age;//4

@property (nonatomic,assign) BOOL sex;//1

@property (nonatomic,assign) char flg;//1

@property (nonatomic,assign) short s;//2

@end

查看生成的结构体如下:

struct Person_IMPL {
    struct NSObject_IMPL NSObject_IVARS;
    BOOL _sex;
    char _flg;
    short _s;
    float _weight2;
    int _age;
    double _weight;
    long _weight1;
    NSString *_name;
};

小细节:用@Property声明的属性(Xcode自动帮生成_开头的成员变量),字节低的排前面,相同字节数的变量根据代码顺序排列;自己声明的成员变量,根据代码的顺序进行排列。

标签: 暂无
最后更新:2021/03/22

CC

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

COPYRIGHT © 2020 CC的博客. ALL RIGHTS RESERVED.

Theme Kratos

豫ICP备2023032048号