Objective-C中,我们可以通过一些方法来获取一个NSObject对象占用多少字节NSObject实例对象的成员变量字节大小* 获取一个NSObject实例对象的成员变量所占用的字节大小,可以用`runtime`的api, `class_getInstanceSize`来获取,得到`8` /** * Returns the size of instances of a class.
*
* @param cls A class object.
*
* @return The size in bytes of instances of the class \e cls, or \c 0 if \e cls is \c Nil.
*/
OBJC_EXPORT size_t
class_getInstanceSize(Class _Nullable cls)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);* 也可以通过`malloc`库里的api,`malloc_size`来获取,得到`16` extern size_t malloc_size(const void *ptr);/* Returns size of given ptr */#import <Foundation/Foundation.h>#import <objc/runtime.h>#import <malloc/malloc.h>// NSObject Implementationstruct NSObject_IMPL { Class isa; // 8个字节};// 指针// typedef struct objc_class *Class;int main(int argc, const char * argv[]) { @autoreleasepool { NSObject *obj = [[NSObject alloc] init]; // 16个字节 // 获得NSObject实例对象的成员变量所占用的大小 >> 8 NSLog(@"%zd", class_getInstanceSize([NSObject class])); // 获得obj指针所指向内存的大小 >> 16 NSLog(@"%zd", malloc_size((__bridge const void *)obj)); // 什么平台的代码 // 不同平台支持的代码肯定是不一样 // Windows、mac、iOS // 模拟器(i386)、32bit(armv7)、64bit(arm64) // 可以通过 命令行工具,生成C++文件 // xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp // 然后把编译成功的cpp文件,拖入到工程中,注意 Copy items if needed 不勾选 // 然后Build Phases中删除main-arm64.cpp编译选项(选中文件点减号或按delete键) // 这样文件不参与编译就不会报错了 } return 0;}NSObject对象本质上是C++的结构体,结构大概长这样// NSObject Implementationstruct NSObject_IMPL { Class isa; // 8个字节};* 地址`https://opensource.apple.com/tarballs/objc4/`
* 选择版本号最新的下载查看查看源码发现,一旦发现inline size_t instanceSize(size_t extraBytes) const { if (fastpath(cache.hasFastInstanceSize(extraBytes))) { return cache.fastInstanceSize(extraBytes); } size_t size = alignedInstanceSize() + extraBytes; // CF requires all objects be at least 16 bytes. if (size < 16) size = 16; return size; }CoreFoundation框架里的硬性规定,内存对齐,小于16就会设置为16image.png
Xcode菜单栏选中Debug -> Debug Workflow -> View Memoryimage.png
image.png
image.png
image.png
NSObject对象占用多少字节16个字节给NSObject对象(通过malloc_size函数获得)NSObject对象内部只使用了8个字节的空间(64bit环境下,可以通过class_getInstanceSize函数来获取),其实就是isaStudent继承自NSObjectstruct Student_IMPL { Class isa; int _no; int _age;};@interface Student : NSObject{ @public int _no; int _age;}@end@implementation Student@endint main(int argc, const char * argv[]) { @autoreleasepool { Student *stu = [[Student alloc] init]; stu->_no = 4; stu->_age = 5; // 16 NSLog(@"%zd", class_getInstanceSize([Student class])); // 16 NSLog(@"%zd", malloc_size((__bridge const void *)stu)); struct Student_IMPL *stuImpl = (__bridge struct Student_IMPL *)stu; // no is 4, age is 5 NSLog(@"no is %d, age is %d", stuImpl->_no, stuImpl->_age); } return 0;}image.png
@interface Person: NSObject{ int _age;}@end@implementation Person@end@interface Student : Person{ int _no;}@end@implementation Student@endint main(int argc, const char * argv[]) { @autoreleasepool { Person *person = [[Person alloc] init]; // 16 NSLog(@"person --- %zd", class_getInstanceSize([Student class])); // 16 NSLog(@"person --- %zd", malloc_size((__bridge const void *)person)); Student *stu = [[Student alloc] init]; // 16 NSLog(@"stu --- %zd", class_getInstanceSize([Student class])); // 16 NSLog(@"stu --- %zd", malloc_size((__bridge const void *)stu)); } return 0;}image.png
Person对象,一个Student对象占用多少内存空间?image.png
16)的倍数Objective-C不同数据类型占用字节大小sizeof来获取不同数据类型占用字节大小sizeof其实不是一个函数,仅仅只是一个操作运算符罢了,编译时就确定了的类型 | 32位机器 | 64位机器 |
|---|---|---|
BOOL | 1 | 1 |
bool | 1 | 1 |
int | 4 | 4 |
short | 2 | 2 |
long | 4 | 8 |
long long | 8 | 8 |
NSInteger | 4 | 8 |
float | 4 | 4 |
double | 8 | 8 |
CGFloat | 4 | 8 |
char | 1 | 1 |
指针地址 | 4 | 8 |
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。