OC对象的本质

Objective-C的面向对象都是基于C/C++的数据结构实现的,而后者又是基于结构体实现的,所以OC转换的最终顺序:

Objective-C -> C/C++ -> 汇编语言 -> 机器语言

创建一个OC的项目,main.m中代码如下:

#import <Foundation/Foundation.h>

@interface Person : NSObject
{   @public
    int _age;
    int _no;
}
@end

@implementation Person



@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *person = [[Person alloc] init];
        person->_age = 10;
        person->_no = 20;
        int temp = 10;
        NSLog(@"%zd", class_getInstanceSize([Person class]));
        NSLog(@"%zd",malloc_size((__bridge const void *)(person)));
        NSLog(@"%zd", sizeof(temp));
    }
    return 0;
}

运用指令xcrun  -sdk  iphoneos  clang  -arch  arm64  -rewrite-objc main.m -o main.cpp 将main.m文件转化为c++文件

可得到如下代码:

struct Person_IMPL {
    struct NSObject_IMPL NSObject_IVARS;
    int _age;
    int _no;
};

其实可以看出类Person被转成Person_IMPL的结构体:

可以用如下的代码完成等价实现:

#import <Foundation/Foundation.h>
#import <malloc/malloc.h>
#import <objc/runtime.h>

struct NSObject_IMPL {
    Class isa;
};
struct Person_IMPL {
    struct NSObject_IMPL NSObject_IVARS;
    int _age;
    int _no;
};

@interface Person : NSObject
{   @public
    int _age;
    int _no;
}
@end

@implementation Person



@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *person = [[Person alloc] init];
        person->_age = 10;
        person->_no = 20;
        int temp = 10;
        NSLog(@"%zd", class_getInstanceSize([Person class]));
        NSLog(@"%zd",malloc_size((__bridge const void *)(person)));
        NSLog(@"%zd", sizeof(temp));
        
        struct Person_IMPL *peoImpl = (__bridge struct Person_IMPL *)(person);
        NSLog(@"no is %d, age is %d", peoImpl->_no, peoImpl->_age);
    }
    return 0;
}

打印结果如下:

OC对象的本质[13731:471379] 16
OC对象的本质[13731:471379] 16
OC对象的本质[13731:471379] 4
OC对象的本质[13731:471379] no is 20, age is 10

整个person对象分配了16个字节,而且该对象实际使用也是16个字节,而int是四个字节,也就是说NSObject_IMPL是8个字节

关于转换cpp文件的指令的详解:

xcrun  -sdk  iphoneos  clang  -arch  arm64  -rewrite-objc main.m -o main.cpp
xcrun xcode run
-sdk  具体哪种设备
-arch 哪种架构

 

posted @ 2020-11-16 23:26  木子沉雨  阅读(136)  评论(0编辑  收藏  举报