Object_c底层细节

150 篇文章 0 订阅

首先我们来看一下c语言中的struct的内存表示:

typedef struct intStruct

    {

	int i;

} intStruct;


结构体在内存中的表示为:

00 00 00 0A


如果我们简单的定义一个int并赋值,这个int在内存中的表示为:

int i = 10;

00 00 00 0A


结构体和int在内存中的表示是一样的!

如果我们定义的结构体更为复杂,有多个变量,那么它们在内存中是依次排列的(不考虑大端小端的情况)。在内存中排列一致,导致intStructint可以相互转换。

当你在看apple开发文档时发现toll-free bridged这种字眼时(经常发生在NS***CF***之间),表明它们是可以相互转换的,因为它们在内存中的排列是一致的。例如NSarrayCFArrayRef(NScocoaCFcore foundation)

CFArrayRef arrayRef = //some value;

NSArray *array = (NSArray*)arratRef;

我们回头再看NSObject的定义,理解下为什么objective-c称之为objective-c.

@interface NSObject<NSObject>{

  Class isa;

}


@interface关键字告诉编译器:请将NSObject作为objective-c的一个类名,并将它转换成一个struct

struct NSObject{

Class isa;

};


看到了吧,所有的object都是c的结构体。

我们再来看下Class的定义:

typedef struct obj_class * Class;

struct obj_class {

	Class isa

	    Class super_class

	    const char * name

	    long version

	    long info

	    long instance_size

	    struct objc_ivar_list * ivars

	    struct objc_method_list ** methodLists

	    struct objc_cache * cache

	    struct objc_protocol_list * protocols
}


objc_class包含了objc类所需的所有信息,例如变量列表,方法列表,满足的protocol等等。这些信息可以通过gdb将感兴趣的信息打印出来.

我们注意到,NSobjectobjc_class都有一个isa变量,NSObjectisa描述它的元信息(object的类信息)objc_class描述类的类信息(即类的元信息)。这样,同object一样,class也是一种object,它在obj_classisa中可以记录class method(用 + 声明的方法)。

Objc中的runtime reflection就是根据这信息操作的。

方法:

当你在为object定义方法时,例如:

@implementation MyClass


  - (void)someMethod:(NSString*)param


@end


编译器会相应的转换为:

void [-someMethod:](id self, SEL _cmd, NSString *param){} 

_cmd为方法的调用方(receiver), _cmd为方法签名(跟你用@selector得到的一样),后续为方法需要的参数。

当你调用方法时,objective-c会将方法调用都会转成c的方法调用。例如当你在程序里写如下语句时:

[myClass someMethod:@"bytedance"]

会相应的转换为:

objc_msgSend(myClass, @selector(someMethod:), @"bytedance")

@selector本质是一个c string,唯一与c string不同的是在整个内存空间中,同一方法签名的@selector的内存地址是相同的,这样在比较方法签名时候不需要采用同strcmp这么耗时的操作,而通过比较@selector的内存地址即可。

如果调用方没有找到相应的方法,会调用 [NSObject  resolveInstanceMethod]方法给调用方一次处理的机会

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值