前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS底层原理--OC对象的本质

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

作者头像
谦谦君子修罗刀
发布2019-03-22 11:38:49
6380
发布2019-03-22 11:38:49
举报

哇哦~距离上次更新笔记已是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
复制
struct NSObject_IMPL {
    Class isa;
}

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

2、NSObject对象占多少内存?

分析: 通过打印

代码语言:javascript
复制
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
复制
struct Student IMPL {
    struct NSObject_IMPL NSObject_IVARS;
    // 还有Student类的成员变量
    //……
}

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

代码语言:javascript
复制
#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 删除。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、NSObject的本质是什么?
  • 2、NSObject对象占多少内存?
  • 3、若一个Student类继承自NSObject类,那么Student类的对象占多少内存?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档