ASP源码.NET源码PHP源码JSP源码JAVA源码DELPHI源码PB源码VC源码VB源码Android源码
当前位置:首页 >> 低调看直播体育app软件下载 >> IOS开发 >> NSObject 底层本质

NSObject 底层本质(3/5)

来源:网络整理     时间:2018-11-01     关键词:

本篇文章主要介绍了" NSObject 底层本质",主要涉及到方面的内容,对于IOS开发感兴趣的同学可以参考一下: 一、OC 转 C/C++二、NSObject 对象内存布局三、NSObject 内存大小四、OC 对象内存布局五、OC 对象内存大小一、OC 转 C/C++OC...

size_t instanceSize(size_t extraBytes) {
        size_t size = alignedInstanceSize() + extraBytes;
        // CF requires all objects be at least 16 bytes.
        if (size < 16) size = 16;
        return size;
    }

3.4 小结

综上,系统分配了 16 个字节给 NSObject 对象(通过 malloc_size 函数获得),但 NSObject 对象内部只使用了 8 个字节的空间,这8个字节主要用来存放 isa( 64bit 环境下,可以通过 class_getInstanceSize 函数获得)。

四、OC 对象内存布局

4.1 简单对象

@interface Student : NSObject
{
    @public
    int _no;
    int _age;
}
@end
@implementation Student
@end
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Student *stu = [[Student alloc] init];
    }
    return 0;
}

利用 xcrun 命名生成 C/C++ 代码,代码中会包含如下部分:

struct Student_IMPL {
    Class NSObject_IMP NSObject_IVARS;
    int _no;
    int _age;
};

其中NSObject_IMP 定义为:

struct NSObject_IMPL {
    Class isa; 
};

Student_IMP底层进而可转为如下结构,不难看出如果对象之间存在继承关系,最终子类转化对应的结构体会包含父类的结构体成分,且父类结构体成份在前。

struct Student_IMPL {
    Class isa;
    int _no;
    int _age;
};

为了进一步说明OC对象底层是结构体实现的,可以将OC对象强制转为结构体,发现代码依然正常运行。

Student *stu = [[Student alloc] init];
stu->_no = 4;
stu->_age = 5;
//使用__bridge 将 OC 转为 C
struct Student_IMPL *stuImpl = (__bridge struct Student_IMPL *)stu;
NSLog(@"no is %d, age is %d", stuImpl->_no, stuImpl->_age);

结合上述代码,可以总结出Student对象的底层实现结构图:

相关图片

相关文章