OC对象的本质

Objective-C本质

Objective-C -----> C/C++ -----> 汇编语言 -----> 机器语言
Objective-C的面向对象都是基于C/C++的数据结构实现的(结构体)

将OC代码转换成C/C++代码的命令

clang -rewrite-objc OC源文件 -0 输出的CPP文件
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc OC源文件 -0 输出的CPP文件
注意:如果需要链接其他框架,使用-framework参数(例如:-framework UIKit)
iphoneos:什么平台(不同平台支持的代码肯定是不一样,mac、iOS)
-arch arm64:什么架构(模拟器(i386)、32bit(armv7)、64bit(arm64))

一个NSObject对象占用多少内存?

系统分配了16个字节给NSObject对象(malloc_size可获得)
但NSObject对象内部只使用了8个字节的空间(class_getInstanceSize可获得)
NSObject *obj = [[NSObject alloc] init];
//	NSObject的定义
@interface NSObject {
    Class isa;
}
//	底层实现
struct NSObject_IMPL {
	Class isa;
};
//	Class实际是一个指向结构体的指针
typedef struct objc_class *Class;
//	指针在64bit 下 占8个字节;32bit 下 占4个字节
============================== class_getInstanceSize ==============================
/*	
	获得NSObject实例对象的成员变量所占内存的大小(内存对齐后的大小)
	创建一个实例对象,至少需要多大的内存
	#import <objc/runtime.h>
*/   
class_getInstanceSize([NSObject class]);
//	class_getInstanceSize底层实现
size_t class_getInstanceSize(Class cls)
{
    if (!cls) return 0;
    return cls->alignedInstanceSize();
}
// Class's ivar size rounded up to a pointer-size boundary.
uint32_t alignedInstanceSize() {
	return word_align(unalignedInstanceSize());
}
============================== malloc_size ==============================
/*
	获得obj指针所指向内存的大小
	创建一个实例对象,实际上分配多大的内存
	#import <malloc/malloc.h>
*/  
malloc_size((__bridge const void *)obj);
/*	
	allocWithZone底层实现
	接下来看看 _class_createInstanceFromZone函数的实现
*/
id
_objc_rootAllocWithZone(Class cls, malloc_zone_t *zone __unused)
{
    // allocWithZone under __OBJC2__ ignores the zone parameter
    return _class_createInstanceFromZone(cls, 0, nil,
                                         OBJECT_CONSTRUCT_CALL_BADALLOC);
}

/*	_class_createInstanceFromZone的实现
	(id)calloc(1, size) 为C语言分配内存空间
	这个size来至 size_t size = cls->instanceSize(extraBytes);
	接下来看看 instanceSize的实现
*/
static ALWAYS_INLINE id
_class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone,
                              int construct_flags = OBJECT_CONSTRUCT_NONE,
                              bool cxxConstruct = true,
                              size_t *outAllocatedSize = nil)
{
    ASSERT(cls->isRealized());

    // Read class's info bits all at once for performance
    bool hasCxxCtor = cxxConstruct && cls->hasCxxCtor();
    bool hasCxxDtor = cls->hasCxxDtor();
    bool fast = cls->canAllocNonpointer();
    size_t size;

    size = cls->instanceSize(extraBytes);
    if (outAllocatedSize) *outAllocatedSize = size;

    id obj;
    if (zone) {
        obj = (id)malloc_zone_calloc((malloc_zone_t *)zone, 1, size);
    } else {
        obj = (id)calloc(1, size);
    }
    if (slowpath(!obj)) {
        if (construct_flags & OBJECT_CONSTRUCT_CALL_BADALLOC) {
            return _objc_callBadAllocHandler(cls);
        }
        return nil;
    }

    if (!zone && fast) {
        obj->initInstanceIsa(cls, hasCxxDtor);
    } else {
        // Use raw pointer isa on the assumption that they might be
        // doing something weird with the zone or RR.
        obj->initIsa(cls);
    }

    if (fastpath(!hasCxxCtor)) {
        return obj;
    }

    construct_flags |= OBJECT_CONSTRUCT_FREE_ONFAILURE;
    return object_cxxConstructFromClass(obj, cls, construct_flags);
}

/*	
	instanceSize的实现
	可以看到 所有的对象至少是16个字节(if (size < 16) size = 16;)
*/
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;
}

//	iOS分配内存都是16的倍数
#define NANO_MAX_SIZE			256 /* Buckets sized {16, 32, 48, ..., 256} */

/*	也可以通过查看内存的方式
	1、取得对象的指针地址
	2、Debug ---> Debut Workflow ---> View Memory
*/

============================== 示例 1 ==============================
@interface Student : NSObject
{
    int _no;
}
@property (nonatomic, assign) int age;

@end

@implementation Student

@end

//	将OC代码转成C/C++代码如下
struct Student_IMPL {
	struct NSObject_IMPL NSObject_IVARS;
	int _no;
	int _age;
};

struct NSObject_IMPL {
	Class isa;
};
============================== 示例 2 ==============================
//	Person 继承至 NSObject
@interface Person : NSObject
{
    int _no;
}

@end

@implementation Person

@end
//	Student 继承至 Person
@interface Student : Person
{
    int _age;
}

@end

@implementation Student

@end
//	将OC代码转成C/C++代码如下
struct Student_IMPL {
	struct Person_IMPL Person_IVARS;
	int _age;
};

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

struct NSObject_IMPL {
	Class isa;
};
PS 此文为学习 李明杰 老师的 iOS底层原理课程所写笔记
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值