美文网首页
OC对象的本质

OC对象的本质

作者: sajiner | 来源:发表于2018-03-08 17:44 被阅读266次

Objective-C的本质是什么

学过编程的都知道,程序的编译原理即是由高级语言到机器语言的过程。Objective-C属于一种面向对象的高级语言,其编译过程如下:


屏幕快照 2018-03-08 下午4.42.44.png

即:Objective-C的面向对象都是基于C/C++的数据结构实现的,而Objective-C的对象、类主要是基于C/C++的结构体实现的,本质上Objective-C的对象、类就是结构体

为什么OC对象的本质是结构体

NSObject

  • 首先我们先创建一个程序


    屏幕快照 2018-03-08 下午4.49.03.png
  • 在main.m文件中创建一个NSObject的对象
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSObject *obj = [[NSObject alloc] init];
    }
    return 0;
}
  • 使用终端将main.m编译成.cpp文件,命令如下:
    xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main.cpp
    *打开main.cpp文件,搜索NSObject,可找到如下代码:
istruct NSObject_IMPL {
    Class isa;
};

即:创建的obj就是一个结构体

自定义的类

在main.m文件中创建一个NSObject的对象

@interface Student: NSObject {
    @public
    int _age;
    int _score;
}
@end

@implementation Student
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Student *stu = [[Student alloc] init];
        stu->_age = 4;
        stu->_score=80;
    }
    return 0;
}
  • 同上的方式生成main.cpp文件,搜索Student,可看到如下内容:
struct Student_IMPL {
    struct NSObject_IMPL NSObject_IVARS; /// 相当于 Class isa;
    int _age;
    int _score;
};
/// 由上得到,即一个初创的Student对象所占的内存大小为:isa的大小
 + int的大小*2
struct Student_IMPL {
    Class isa;
    int _age;
    int _score;
};
  • 假设Student对象是一个结构体的话
/// 定义这样的结构体
struct Student_IMPL {
    Class isa;
    int _age;
    int _score;
};

@interface Student: NSObject {
    @public
    int _age;
    int _score;
}
@end

@implementation Student
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Student *stu = [[Student alloc] init];
        stu->_age = 4;
        stu->_score=80;
       
        struct Student_IMPL *stu2 = (__bridge struct Student_IMPL *)stu;
        /// 如果打印结果是 4 - 80 的话,即可证明student对象本质上就是一个结构体
        NSLog(@"%d - %d", stu2->_age, stu2->_score);
    }
    return 0;
}

由打印结果反推得出:student对象本质上就是一个结构体

扩展:NSObject所占内存大小是多少?

因为OC对象的本质是结构体,那NSObject所占的内存大小就是结构体指针所占的大小。
其实不然,准确的说法是:(以64bit为例)
1、从内存中动态分配的大小是由malloc_size()函数获取的,即16
2、NSObject对象真正使用的大小是 8 (可以通过运行时中的class_getInstanceSize:方法直接获取NSObject的内存大小)


20180927补充
malloc_size()为类对象动态分配的内存大小,是补齐之后的大小,即如果一个类对象需要的内存大小为81,通过malloc_size()方法获取的大小为96,即16的倍数;
class_getInstanceSize()方法获取的内存大小也是补齐之后的大小,补齐规则按照类的成员变量所占内存最大值的整数倍

相关文章

网友评论

      本文标题:OC对象的本质

      本文链接:https://www.haomeiwen.com/subject/gxpyfftx.html