iOS底层原理总结--OC对象的本质(一) - 掘金xcode
iOS底层原理总结--OC对象的分类:instance、class、meta-calss对象的isa和superclass - 掘金post
...spa
思考: 若是个人Student有三个成员变量 那么会占用对少个字节? (class_getInstanceSize([Student class]) 的输出是多少? malloc_size((__bridge const void *)stu的输出是多少? )
3d
#import <malloc/malloc.h>
#import <OBJC/runtime.h>
///> Student类
@interface Student: NSObject{
@public
int _no;
int _age;
int _gender;
}
///> 实际底层的结构体 结构
//struct Student_IMPL{
// Class isa,
// int _no,
// int _age;
// int _gender;
//}
@end
@implementation Student
@end
///> main
int main(int argc, char * argv[]) {
@autoreleasepool {
Student *stu = [[Student alloc]init];
stu->_no = 4;
stu->_age = 5;
stu->_gender = 1;
NSLog(@"%zd", class_getInstanceSize([Student class]));
NSLog(@"%zd", malloc_size((__bridge const void *)stu));
/**输出结果 24 32 */
}
return 0;
}
复制代码
可使用Xcode自带的工具去查看 系统分配的内存和使用的内存状况。指针
首先咱们须要拿到stu对象的内存地址: 调试
这里咱们的内存地址为:<Student: 0x600002746b60>code
由上图分析:咱们能够得出 stu实际上在内存中分配了32个字节的内存空间 也就是 malloc_size() 所输出的开辟内存空间的字节数。
cdn
class_getInstanceSize 顾名思义 获取类的实例大小 isa占用8个 + _no:4个 + _age4个 + _gender4个
@interface Student: NSObject{
@public
Class isa; ///> 8
int _no; ///> 4
int _age; ///> 4
int _gender; ///> 4
} /// 计算相加后 为20个,
复制代码
结构体存在一个内存对其的操做,这样有利于CPU的访问, 在CO中用到的内存对其的一条规则就是: 结构体为了保证内存对其 最重的真用内存必定是占用最大的一个变量的倍数, 在这里咱们isa占用了8个字节数, 因此虽然实际上只使用了20个字节,可是为了保证内存对其的规则 因此使用了24个字节,
若是咱们有4个成员变量的话:
@interface Student: NSObject{
@public
Class isa; ///> 8
int _no; ///> 4
int _age; ///> 4
int _gender; ///> 4
int _height; ///> 4
} /// 计算相加后 为24个,
复制代码
咱们真用的内存仍是24,开辟依旧是32个字节。
若是在增长一个成员变量的话:
@interface Student: NSObject{
@public
Class isa; ///> 8
int _no; ///> 4
int _age; ///> 4
int _gender; ///> 4
int _height; ///> 4
int _weight; ///> 4
} /// 计算相加后 为28个,
复制代码
为了保证内存对其因此大小为32个字节,开辟依旧是32个字节。
malloc_size() 也运用了内存对其的 上篇文章中解释了为何给类的内存分配了16个字节, 因为内存对其的缘由因此stu类分配了32个字节。