第4课-类原理分析基础
[TOC]
1. 内存偏移
结论:获取对象内存中的变量,底层实现方式是对象的首地址+偏移值
1.1 普通指针类型
看下面代码:
int main(int argc, const char * argv[]) {
@autoreleasepool {
int a = 10;
int b = 10;
int *p1 = &a;
int *p2 = &b;
NSLog(@"---%d----%p---%p",a,p1,&p1);
NSLog(@"---%d----%p---%p",b,p2,&p2);
}
return 0;
}
// 打印结果
2022-03-26 22:20:27.415057+0800 003-内存偏移-Demo[33901:9006774] ---10----0x7ff7bfeff22c---0x7ff7bfeff220
2022-03-26 22:20:27.415622+0800 003-内存偏移-Demo[33901:9006774] ---10----0x7ff7bfeff228---0x7ff7bfeff218
由上面打印结果,我们可以得到:
- 变量a的值为10,地址为0x7ff7bfeff22c
- 变量b的值为10,地址0x7ff7bfeff228
- 变量a与变量b是连续分配的,相差4字节,正好是int所占用的字节大小,而且都在栈上分配
- 变量p1指向a,存储a的地址0x7ff7bfeff22c;变量p2指向b,储存b的地址0x7ff7bfeff228
具体如下图:
1.2 对象指针
代码如下:
// 对象指针
ZBPerson *person1 = [ZBPerson alloc];
ZBPerson *person2 = [ZBPerson alloc];
NSLog(@"---%@---%p----%p",person1, person1,&person1);
NSLog(@"---%@---%p----%p",person2, person2,&person2);
// 打印
2022-03-27 07:54:41.002866+0800 003-内存偏移-Demo[37989:9214165] ---<ZBPerson: 0x101404fe0>---0x101404fe0----0x7ff7bfeff210
2022-03-27 07:54:41.356376+0800 003-内存偏移-Demo[37989:9214165] ---<ZBPerson: 0x1014048b0>---0x1014048b0----0x7ff7bfeff208
- 以
ZBPerson *person1 = [ZBPerson alloc]为例,对象执行alloc函数以后,会在堆中申请一块内存,同时返回内存地址 - 在栈上位person1开辟一块内存,保存堆返回的内存地址。
具体如下图:
1.3 数组指针
// 数组指针
int c[4] = {1,2,3,4};
int *d = c;
NSLog(@"%p - %p - %p - %p ",c, &c,&c[0],&c[1]);
NSLog(@"%p - %p - %p ",d,d+1,d+2);
for (int i = 0; i < 4; i++) {
//(d+i) 取地址里面的值
int value = *(d+i);
NSLog(@"value = %d",value);
}
// 打印
2022-03-27 09:00:30.505598+0800 003-内存偏移-Demo[38671:9256893] 0x7ff7bfeff220 - 0x7ff7bfeff220 - 0x7ff7bfeff220 - 0x7ff7bfeff224
2022-03-27 09:00:55.554492+0800 003-内存偏移-Demo[38671:9256893] 0x7ff7bfeff220 - 0x7ff7bfeff224 - 0x7ff7bfeff228
2022-03-27 09:01:13.887985+0800 003-内存偏移-Demo[38671:9256893] value = 1
2022-03-27 09:01:15.954593+0800 003-内存偏移-Demo[38671:9256893] value = 2
2022-03-27 09:01:15.954713+0800 003-内存偏移-Demo[38671:9256893] value = 3
2022-03-27 09:01:15.954785+0800 003-内存偏移-Demo[38671:9256893] value = 4
- 数组在内存中是一块连续空间,数组变量指向这块空间的首地址,也就是第一个元素的首地址,c, &c, &c[0], d指的是同一块内存地址。
- 数组中的元素是int类型,占4字节,因为数组中元素是顺序存储的,所以两个元素之间相差4字节,所以
&c[1]的地址0x7ff7bfeff224与&c[0]的地址0x7ff7bfeff220`相差4字节。 - 指针在数组中支持+,-算数运算,指针+1,表示指针从当前位置移动到下一个元素位置,即数组元素地址=首地址+n*数组元素类型大小(n为当前元素索引值)
图解如下:
我们将上面这种根据首地址和元素字节大小计算当前元素内存的方式称为内存偏移。
2. MachO文件分析
文章参照: juejin.cn/post/701095…