美文网首页
OC对象分析-内存对齐

OC对象分析-内存对齐

作者: 苏苏慢跑 | 来源:发表于2021-03-24 17:00 被阅读0次
  • 第一个内容:对象的内存对齐
    创建了一个Person类,代码如下:
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *nickName;
@end

NS_ASSUME_NONNULL_END

Main函数里打下断点,在alloc后打印下person


image.png

可以看到0x00000001061bf598即为isa的地址,0x6000027687a0为对象存放的起始地址。接着往下走,属性赋值后再次打印


image.png

给Person增加几个属性

@interface Person : NSObject

@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *nickName;
@property (nonatomic, assign) int age;
@property (nonatomic, assign) long height;

@property (nonatomic) char c1;
@property (nonatomic) char c2;


@end

赋值走断点打印下属性

截屏2021-03-24 下午5.16.06.png

可以看到age、c1、c2并没有像name独立一个地址,而是三个一起占了8个字节,这里age 4个字节,c1和c2分别是1个字节,加起来共6个字节,然后字节补齐占了8个字节,这样做自然是为了节省空间。

  • 如果把height类型改成double类型会怎样呢?结果发现完全找不到height的值。


    截屏2021-03-25 上午10.53.24.png

开始时推测0x4066800000000000放的就是180.0,但是打印下发下不是。这是因为double和float是特殊处理的,其实0x4066800000000000放的就是180.0。打印下180.0的16进制,就是0x4066800000000000

  • 内存对⻬的原则

1. 数据成员对⻬规则:结构(struct)(或联合(union))的数据成员,第
⼀个数据成员放在offset为0的地⽅,以后每个数据成员存储的起始位置要
从该成员⼤⼩或者成员的⼦成员⼤⼩(只要该成员有⼦成员,⽐如说是数组,结构体等)的整数倍开始(⽐如int为4字节,则要从4的整数倍地址开始存储。 min(当前开始的位置m n) m = 9 n = 4
9 10 11 12

2. 结构体作为成员:如果⼀个结构⾥有某些结构体成员,则结构体成员要从其内部最⼤元素⼤⼩的整数倍地址开始存储.(struct a⾥存有struct b,b
⾥有char,int ,double等元素,那b应该从8的整数倍开始存储.)

3:收尾⼯作:结构体的总⼤⼩,也就是sizeof的结果,.必须是其内部最⼤
成员的整数倍.不⾜的要补⻬。

这里举例2个struct

struct Struct1 {
    double a;   // 8 (0-7)
    char b;     // 1 [8 1] (8)
    int c;      // 4 [9 4] 9 10 11 (12 13 14 15)
    short d;    // 2 [16 2] (16 17)
}struct1;

// 内部需要的大小为: 17
// 最大属性 : 8
// 结构体整数倍: 24
struct Struct2 {
    double a;   //8 (0-7)
    int b;      //4 (8 9 10 11)
    char c;     //1 (12)
    short d;    //2 13 (14 15) - 16
}struct2;
// 15 -> 16

那么struct嵌套struct呢,应该是两个struct大小的和 24+ 16 = 40

struct Struct1 {
    double a;   // 8 (0-7)
    char b;     // 1 [8 1] (8)
    int c;      // 4 [9 4] 9 10 11 (12 13 14 15)
    short d;    // 2 [16 2] (16 17)
     struct  struct2; // 8 [18  8] 18 19 20 21 22 23 (24 25 ... 从24开始16个字节)
}struct1;

struct Struct2 {
    double a;   //8 (0-7)
    int b;      //4 (8 9 10 11)
    char c;     //1 (12)
    short d;    //2 13 (14 15) - 16
}struct2;
// 15 -> 16

相关文章

网友评论

      本文标题:OC对象分析-内存对齐

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