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()方法获取的内存大小也是补齐之后的大小,补齐规则按照类的成员变量所占内存最大值的整数倍
网友评论