Objective-C的本质
前言...
课程我已经学到第9课了..为了防止忘记..复习一下笔记
Objective-C --> C\C++ --> 汇编语言 --> 机器语言
Objective-C 的面向对象都是基于C\C++的数据结构实现的
结构体
//NSObject Implementation
NSObject_IMPL{
Class isa;//指针 typedef struct objc_class *class;
}
isa指针 64位下占8个字节, 32位占4个字节
实际上分配的内存不是8个字节,是16个字节
为什么会出现这种情况?
从提供的接口里得到的情况如下
1.runtime里边runtime objc4 下载地址
//获得NSObject类的实例对象的成员变量所占有的大小(参数:类对象)
class_getInstanceSize([NSObject class]) //获取实例大小 打出来确实是8
2.malloc 里边(指针指向的内存 void *ptr)
/**
获得obj指针所指向内存的大小
malloc_size(<#const void *ptr#>)
需要对obj 进行强转为c __bridge + 类型
*/
malloc_size((__bridge const void *)obj); // 输出16.
结果验证:
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <malloc/malloc.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSObject *obj = [[NSObject alloc] init];
size_t sizeInstance = class_getInstanceSize([obj class]);
size_t sizeMalloc = malloc_size((__bridge const void *)obj);
NSLog(@"instance is %zu malloc is %zu",sizeInstance,sizeMalloc);
}
return 0;
}
二者之所以不同的原因在于创建的时候的一个限制.
对于obj 对象而言, alloc出来的时候会调用allocWithZone:对于这个可以从辅助下的网址下载最新的objc查看
我直接copy上来
/**
我们调用alloc 方法出新的对象
*/
+ (id)alloc {
return _objc_rootAlloc(self);
}
/**
然后调用了_objc_rootAlloc() 函数,然后调用了callAlloc
*/
id
_objc_rootAlloc(Class cls)
{
return callAlloc(cls, false/*checkNil*/, true/*allocWithZone*/);
}
/**
callAlloc 传参数cls, false以及true
*/
static ALWAYS_INLINE id
callAlloc(Class cls, bool checkNil, bool allocWithZone=false)
{
if (slowpath(checkNil && !cls)) return nil;
//这一部分...与我们想知道的没有什么关系...大家可以自己找一些资料去看看代码像是跟创建对象.内存管理快速分配啥的有关系....
#if __OBJC2__
if (fastpath(!cls->ISA()->hasCustomAWZ())) {
// No alloc/allocWithZone implementation. Go straight to the allocator.
// fixme store hasCustomAWZ in the non-meta class and
// add it to canAllocFast's summary
if (fastpath(cls->canAllocFast())) {
// No ctors, raw isa, etc. Go straight to the metal.
bool dtor = cls->hasCxxDtor();
id obj = (id)calloc(1, cls->bits.fastInstanceSize());
if (slowpath(!obj)) return callBadAllocHandler(cls);
obj->initInstanceIsa(cls, dtor);
return obj;
}
else {
// Has ctor or raw isa or something. Use the slower path.
id obj = class_createInstance(cls, 0);
if (slowpath(!obj)) return callBadAllocHandler(cls);
return obj;
}
}
#endif
//重点在这里 true 的情况下我们调用了allocWithZone:
// No shortcuts available.
if (allocWithZone) return [cls allocWithZone:nil];
return [cls alloc];
}
alloc其实调用的是allocWithZone: 接下来的代码我简要的给大家贴一下...
/**
allocWithZone:调用了_objc_rootAllocWithZone函数
*/
+ (id)allocWithZone:(struct _NSZone *)zone {
return _objc_