一个对象的创建,一般都会伴随着一些属性,但是这些属性是如何排布在对象当中的呢
前提知识
struct Struct1 {
char a;
double b;
int c;
short d;
} MyStruct1;
struct Struct2 {
double b;
int c;
char a;
short d;
} MyStruct2;
按照大小相加得知:
MyStruct1 = 1 + 8 + 4 + 2 = 15 MyStruct2 = 8 + 4 + 1 + 2 = 15
打印两个结构体分别做大小:
明显与相加得到结果不一致.因为 计算机为了方便读取内存, 会进行一次内存优化对齐
例如: Struct1中, 向一个8字节内存中存放char a, 剩余7字节. 继续存放double b. 7个字节不够存放,重新开辟一个8字节存放, 剩余0字节. 继续存放c,重新开辟8字节存放c,剩余4字节. 继续存放d, 4字节足够, 剩余2字节; 实际内存为: 1(a) + 7(补充) + 8(b) + 4(c) + 2(d) + 2(补充) = 24 同理计算Struct2: 实际内存为: 8(b) + 4(c) + 1(a) + 2(d) + 1(补充) = 16
实例化的对象与属性
1.首先创建出一个自定义对象,属性如下
@interface MyTest : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *gender;
@property (nonatomic, assign) int age;
//@property (nonatomic, assign) char test1;
//@property (nonatomic, assign) char test2;
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
MyTest *test = [MyTest alloc];
test.name = @"张三";
test.age = 20;
test.gender = @"男";
size_t size = malloc_size((__bridge const void *)test);
NSLog(@"%@--%zu", test, size);
}
return 0;
}
在NSLog处断点,调试程序.
分析:
-
首先得到test对象大小为32个字节. 一个初始化出来的对象, 内存中前8个字节一定是isa相关. 那么后面相继为属性 name=8bit gender=8bit age=4bit 共计: isa + name + gender + age = 28 由于alloc底层的机制是开辟内存后会对8字节进行做内存对其运算所以应该是再补齐4字节为32字节
-
在控制台打印出test内存
(由于此对象大小为32, 所以只需要打印出32个字节的数据) 分别打印相关内存数据
- 打开test1 test2属性来进行一次验证
初始化属性
test.test1 = 'A';
test.test2 = 'B';
重复第二步得到:
通过对比,只有第二部分内存发生了变化 test1与test2分别只占1个字节, 那么再根据小端模式得知, 42 41就应该是test2与test1的值 分别对应A B的ascII值的65 66. 验证正确附: 大小端模式:
-
大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。
-
小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低。
-
例如: 0x0102(小端) = 0x0201(大端) = 258(iOS中小端模式)