Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >iOS底层原理--OC对象的本质

iOS底层原理--OC对象的本质

作者头像
谦谦君子修罗刀
发布于 2019-03-22 03:38:49
发布于 2019-03-22 03:38:49
70000
代码可运行
举报
运行总次数:0
代码可运行

哇哦~距离上次更新笔记已是long long age 唔~ 为了颜值与技术在线,坚持写笔记,坚持瘦回两位数(emm…貌似暴露了什么)

算春长不老,人愁春老,愁只是,人间有.png

1、NSObject的本质是什么?

分析: OC代码的底层实现实质是C/C++代码,继而编译成汇编代码,最终变成机器语言。 打开终端,进入main.m所在的文件夹,通过clang rewirte-objc main.m -o main.cppxcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp 代码,生成cpp文件。 在cpp文件中找到如下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct NSObject_IMPL {
    Class isa;
}

NSObject的底层实现实质是一个结构体。而结构体中的成员isa是Class类型,通过源码typedef struct objc_class *Class可知它是一个指针。在64为环境下指针占8个字节,而在32位机下是占4个字节。因此该结构体占8个字节(因为该结构体只有一个成员)。

2、NSObject对象占多少内存?

分析: 通过打印

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
NSObject *obj = [[NSObject alloc]init];
NSLog(@"%zd",malloc_size((__bridge const void *)obj));

可知NSObject对象占16个字节。 那么与题1所述结构体中占8个字节是否冲突? 通过打印NSLog(@"%zd",class_getInstanceSize([NSObject class]))获取NSObject类的实例对象的成员变量所占用的(内存对齐之后)大小,显示确实为8个字节。 在objc的源码中找到class_getInstanceSize方法,发现它返回的是cls->alignedInstanceSize(),对它的描述为Class's ivar size rounded up to a pointer-size boundary意指返回成员变量占据的大小。因此创建一个NSObject对象需要分配16个字节,只是真正利用的只有8个字节,即isa这个成员的大小。 事实上,查看allocWithZone的源码发现它最底层的创建实例的方法实际上是调用了C语言的calloc方法,在该方法中,规定若分配的字节不满16将把它分配为16个字节。

3、若一个Student类继承自NSObject类,那么Student类的对象占多少内存?

分析: 新建Student类,添加成员变量。通过clang反编译,打开cpp文件找到Student类的底层实现。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct Student IMPL {
    struct NSObject_IMPL NSObject_IVARS;
    // 还有Student类的成员变量
    //……
}

从这段代码可以看出,若一个类继承自另一个类,则它的底层会将父类的成员变量放在结构体的最前面,此后依次放置本类的成员变量。而从之前的分析可知,NSObject_IMPL的本质就是一个装有成员变量isa的结构体,因此,Student类对象所占的内存为isa的内存8加上Student类成员变量所占的空间。若不满16个字节,会强制分配到16个字节。另,由于<u>内存对齐</u>的规定,结构体的最终大小必须是最大成员的倍数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#import <malloc/malloc.h>
@interface Student:NSObject{
   @public
    int age;
    int no;
    int address;
    NSString *name;
    NSString *name2;
    
}
@end

@implementation Student

@end


int main(int argc, char * argv[]) {
    @autoreleasepool {
        Student *stu = [[Student alloc]init];
        NSLog(@"%zd",malloc_size((__bridge const void *)stu));
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

打印结果如下图所示:

结果

附:苹果官方开放源码

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.03.21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
OC 对象的本质
一个 NSObject 对象占用多少内存? 一个指针变量所占用的大小(64bit->8个字节,32bit->4个字节) 我们平时编写的Objective-C代码,底层实现都是C/C++代码,Objective-C的面向对象都是基于C/C++的数据结构实现的。 Objective-C -> C/C++ -> 汇编语言 -> 机器语言 如果想研究一些本质问题,最好将Objective-C代码转化成C/C++代码,才比较容易分析出来原理。 Objective-C的对象、类主要是基于C/C++的什么数
用户1890628
2018/05/10
1.2K0
iOS底层原理总结 - 探寻OC对象的本质
iOS底层原理总结 - 探寻OC对象的本质 对小码哥底层班视频学习的总结与记录。面试题部分,通过对面试题的分析探索问题的本质内容。 面试题:一个NSObject对象占用多少内存? 探寻OC对象的
xx_Cc
2018/05/10
1.3K0
(1)Objective-C的本质
众说周知,我们平时编写的OC代码,底层都是C/C++实现的 我们可以通过一个终端指令,将我们的OC代码转换成C/C++代码 xcrun -sdk iphoneos clang -arch arm64
czjwarrior
2018/05/28
4250
面试驱动技术之 - isa && 元类 && 函数调用
以MNPerson为例,里面的成员变量有不同类型是,比如int、double、NSString 类型,假如在C/C++ 中用数组存储,显然是不太合理的
小蠢驴打代码
2019/01/28
1K0
面试驱动技术之 - isa && 元类 && 函数调用
ios底层原理
API,用于获取类的实例对象所占用的内存大小,并返回具体的字节数,其本质就是获取实例对象中成员变量的内存大小
ruochen
2021/11/22
8220
iOS底层—OC对象的本质与isa
我们已经学习了对象的初始化、内存对齐等内容。这篇文章将深入学习探究对象的本质、对isa进行分析。
CC老师
2022/01/11
6550
iOS底层—OC对象的本质与isa
关于NSObject对象的内存布局,看我就够了!
Objective-C语言是一门高级语言,底层是由C/C++语言实现。要想从本质上了解Objective-C对象的底层数据结构和内存布局,就需要一步步揭开那最神秘的面纱。
Jacklin
2020/02/18
1.9K0
关于NSObject对象的内存布局,看我就够了!
OC源码剖析对象的本质
@property (nonatomic, copy) NSString *p_name;
艳艳代码杂货店
2021/09/26
3610
IOS底层原理之NSObject的结构
在OC程序中,我们知道NSObject是“万物之源”,所有的类的都继承自NSObject,我们疑惑的是在OC的底层NSObject是什么样的?
CC老师
2022/01/12
7520
IOS底层原理之NSObject的结构
iOS 进阶之 Block 的本质及原理
相信稍微有点开发经验的开发者,应该都对 block 有一定的了解。刚开始使用 block 的时候,可能觉得很方便。知道怎么去用,但是知其然知其所以然的态度来分析一下 block 的原理和内部结构是什么。
网罗开发
2021/01/29
7190
iOS 进阶之 Block 的本质及原理
iOS底层原理(一):OC对象实际占用内存与开辟内存关系
Objective-C编程语言是C语言的超集,在C语言的基础上加入了面向对象的内容。OC可以和C/C++混合使用,OC对象都可以转化为C/C++结构体表示。
CC老师
2023/03/23
7680
iOS底层原理(一):OC对象实际占用内存与开辟内存关系
OC底层探索06-isa本身藏了多少信息你知道吗?OC底层探索06-isa本身藏了多少信息你知道吗?
一直都说类最终都会编译为struct,可是怎么验证呢?编译后的结构体内部都会有些什么东西呢?
用户8893176
2021/08/09
4120
OC底层探索06-isa本身藏了多少信息你知道吗?OC底层探索06-isa本身藏了多少信息你知道吗?
iOS 知识点回顾(一)
温故而知新 目录 一个NSObject对象占用多少内存? 对象的isa指针指向哪里? OC的类信息存放在哪里? iOS用什么方式实现对一个对象的KVO?(KVO的本质是什么?) KVC Category +load方法和+initialize方法 Block _ _weak 1. 一个NSObject对象占用多少内存? 系统分配了16个字节给NSObject对象(通过malloc_size函数获得),但NSObject对象内部只使用了8个字节的空间(64bit环境下,可以通过class_getInst
且行且珍惜_iOS
2019/12/30
6750
iOS底层原理总结 - 探寻Runtime本质(四)
首先来看一道面试题。 下列代码中Person继承自NSObject,Student继承自Person,写出下列代码输出内容。
xx_Cc
2018/08/02
9730
iOS底层原理总结 - 探寻Runtime本质(四)
OC对象原理(二)
上面的代码中,如果我们覆写了该类的allocWithZone方法,那么就会走到第31行的逻辑;不过一般而言我们是不会自己去覆写allocWithZone方法的,所以一般都会走第8~28行的逻辑。
拉维
2021/10/20
8030
iOS底层原理之Runimte 运行时&方法的本质
前面探究了类里面的重要的变量,iOS 底层原理之cache分析分析了缓存方法调用流程。
CC老师
2022/01/11
4470
iOS底层原理之Runimte 运行时&方法的本质
ios 底层原理 : 类与类结构分析
类的分析 类的分析主要是分析 isa 的走向与继承关系 准备 创建两个类 1.继承自 NSObject 的 LGPerson @interface LGPerson : NSObject { NSString *hobby; } @property(nonatomic,copy)NSString * lg_name; - (void)sayHello; + (void)sayBye; @end @implementation LGPerson - (void)sayHello { } +
conanma
2021/10/28
7000
对象原理探究(二)
结构体(struct)或者联合体(union)的数据成员,第一个数据成员会放在offset为0的地方,之后的每个数据成员存储的起始位置要从该成员大小(如果该成员有子成员,比如数组、结构体等,那么就从子成员大小)的整数倍开始。
拉维
2021/03/10
4280
对象原理探究(二)
「类与对象」如何准确获取对象的内存大小?
在上篇文章「类与对象」揭秘本质的第一步中,揭秘NSObject类的底层数据结构,如下所示:
Jacklin
2019/12/26
5.1K0
「类与对象」如何准确获取对象的内存大小?
一个NSObject对象占用多少个字节
在Objective-C中,我们可以通过一些方法来获取一个NSObject对象占用多少字节 代码获取NSObject实例对象的成员变量字节大小 * 获取一个NSObject实例对象的成员变量所占用的字节大小,可以用`runtime`的api, `class_getInstanceSize`来获取,得到`8` /** * Returns the size of instances of a class. * * @param cls A class object. * * @retur
ruochen
2021/11/22
7270
相关推荐
OC 对象的本质
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验