OC对象内存布局与isa指针

news/2024/12/29 20:24:24/

文章目录

  • 一、Objective-C的本质
  • 二、一个objc对象如何进行内存布局?考虑父类的情况
  • 三、一个objc对象的isa指针指向什么?有什么作用
  • 四、objc对象的类方法和实例方法有什么本质区别和联系?

一、Objective-C的本质

  • Objc的底层实现是C\C++代码:objc->C\C+±>汇编->机器语言
  • Objc的对象,类主要是基于C\C++中的结构体实现
  • 将Objc代码转换为C\C++代码
xcrun  -sdk  iphoneos  clang  -arch  arm64  -rewrite-objc OC源文件  -o  输出的CPP文件

二、一个objc对象如何进行内存布局?考虑父类的情况

类结构图:
请添加图片描述

对象的底层实现

  • oc的代码
@interface Person : NSObject
{@publicint _age;
}
@end@interface Student : Person
{@publicint _no;
}
@end@interface Graduate : Student
{@publicint grade;
}
@end@implementation Graduate@end

对应的C++代码

struct NSObject_IMPL {Class isa;
};struct Person_IMPL {struct NSObject_IMPL NSObject_IVARS; // 8int _age; // 4
};struct Student_IMPL {struct Person_IMPL Person_IVARS; int _no; 
}; Student *stu = [[Student alloc] init];stu->_age = 2;stu->_no = 3;NSLog(@"stu - %zd", class_getInstanceSize([Student class]));  // 16NSLog(@"stu - %zd", malloc_size((__bridge const void *)stu)); // 16Graduate *grade = [[Graduate alloc] init];
grade->_age = 7;
grade->_no = 8;
grade->grade = 9;
NSLog(@"grade - %zd", class_getInstanceSize([Graduate class])); // 24
NSLog(@"grade - %zd", malloc_size((__bridge const void *)grade)); // 32
  • 64位系统下, 可以看出,编译给Person分配了16个字节,实际用到12个字节,还有4个字节没有使用, Student对象继承Person对象,Student对象实际会继续使用Person对象内存中没有使用的4个字节,所以Student对象的内存大小是16个字节,Grade继承Student类,实际占用的内存大小为20个字节,由于内存对齐原因,以8个字节内存对齐,所以会使用24个字节,编译器分配了32个字节
  • 内存对齐:结构体的大小必须是最大成员大小的倍数

Student内存布局.png

总结:

  • 就是多了一个isa指针,isa的大小由编译器,系统决定,内存分配编译器按照内存对齐进行大小分配,分配的内存,不一定会完全用完
    class_getInstanceSize获取实例对象至少占用的内存
    malloc_size获取编译器给实例对象对象分配的内存的大小
    在 libmalloc源码中定义了 #define NANO_MAX_SIZE 256 /* Buckets sized {16, 32, 48, 64, 80, 96, 112, …}表示在iOS系统中每次最少分配16个字节,或者每次分配的字节数是16的倍数,每次最多分配256字节

三、一个objc对象的isa指针指向什么?有什么作用

  • 实例变量的isa指针指向他所属的类
  • 类的isa指针指向他所属的原类
  • 原类的根类的isa指针指向他本身
  • 当我们向对象发送消息时,可以根据isa指针指向寻找原类的方法列表是否存在这个消息,确定是否可以响应方法,作用就是帮我们寻找方法

四、objc对象的类方法和实例方法有什么本质区别和联系?

  • 区别:
  1. 属于谁
    类方法属于类对象 [NSString stringwithFormat:]
    实例方法属于实例对象 [str length]

  2. 谁调用
    类方法 类对象调用
    实例方法 实例对象调用

  3. self是什么
    在类方法里面,self表示类对象
    在实例方法里,self表示实例对象

  4. 是否可以访问成员变量
    类方法里 不可以访问成员变量
    实例方法 可以访问成员变量

  5. 方法调用问题
    类方法里 可以调用实例方法也可以调用类方法
    实例方法里 继可以调用实例方法也可以调用类方法


http://www.ppmy.cn/news/993123.html

相关文章

技术能力提升-《系统架构设计师教程》

在最近的月度读书会上,国林哥分享了下对《系统架构设计教程》的一点见解,在技术管理摸爬滚打了多年,觉得这个认证还是有一定价值,希望对有兴趣了解这门认证考试的朋友有所帮助,起到抛砖引玉的作用。 国林哥从以下四个方…

IO网络模型

文章目录 1、用户空间和内核态空间2、网络模型-阻塞IO3、网络模型-非阻塞IO4、网络模型-IO多路复用5、网络模型-信号驱动6、网络模型-异步IO7、对比 1、用户空间和内核态空间 服务器大多都采用Linux系统,例如: ubuntu和Centos 都是Linux的发行版,发行版…

爬虫小白-如何调试列表页链接与详情链接不一样并三种方式js逆向解决AES-ECB

目录 一、网站分析二、定位监听三、熟悉AES-ECB四、调试分析五、node运行js六、Python执行js 一、网站分析 三年前的案例,我的原始文章网站 ,如图我们直接点击标题进入到详情页,链接会发生跳转,且与我们在详情看到的链接&#xf…

前端面试题 —— Vue (三)

目录 一、v-model 可以被用在自定义组件上吗?如果可以,如何使用? 二、描述下Vue自定义指令 (1)自定义指令基本内容 (2)使用场景 (3)使用案例 三、Vue是如何收集依赖…

前端请求传输token到后端的两种方式

谈谈 cookie & session & jwt - 掘金 前端在每次请求时把token放在请求头中发送给后端,目前有两种方式: 一是通过cookie的形式,即把token放在cookie中,每次浏览器会自动帮我们带过去,不需要我们自己设置。 二…

美颜SDK开发指南:优化直播人像表现

在当今社交媒体和直播平台的流行趋势下,越来越多的用户渴望在直播中展现更加自信和美丽的一面。本文将探讨美颜SDK的开发指南,介绍其优化直播人像表现的重要性以及关键的技术要点。 一、用户为什么离不开美颜? 美颜SDK作为一种集成在直播应用…

php://filter绕过死亡exit

文章目录 php://filter绕过死亡exit前言[EIS 2019]EzPOP绕过exit 参考 php://filter绕过死亡exit 前言 最近写了一道反序列化的题,其中有一个需要通过php://filter去绕过死亡exit()的小trick,这里通过一道题目来讲解 [EIS 2019]EzPOP 题目源码&#…

IT职场笔记

MySQL笔记之一致性视图与MVCC实现 一致性读视图是InnoDB在实现MVCC用到的虚拟结构,用于读提交(RC)和可重复度(RR)隔离级别的实现。 一致性视图没有物理结构,主要是在事务执行期间用来定义该事物可以看到什…