iOS Runtime

简单介绍下runtime
http://www.cocoachina.com/ios/20141018/9960.html

http://zhiwei.li/text/2014/08/09/objective-c运行时objc_msgsend_stret/

我们在运行代码的时候 像下面这个方法:

[target doMethodWith:var1]; 运行时会转换为 objc_msgSend(target,@selector(doMethodWith:),var1); C语言函数指针

关于runtime的一些问题:http://blog.csdn.net/a19860903/article/details/45044701

第一、文章里面有一个问题:

下面的代码输出什么?

@implementation Son : Father

  • (id)init

{

self = [super init];

if (self)

{

    NSLog(@"%@", NSStringFromClass([self class]));

    NSLog(@"%@", NSStringFromClass([super class]));

}

return self;

}

@end

答案:都输出 Son (前提是father和son类都没有重写class这个方法,而是调用的nsobject的class方法)

首先对于这个题,如果Son类没有重写class方法,而Father类里重写了NSObject的class这个方法,那么[self class] 会去调用父类Father里的class方法,如果想要上面输出: Son 和 Father这种正确的类名,那么就要重写两个类的class方法:

Son.m
//- (Class)class OBJC_SWIFT_UNAVAILABLE(“use ‘anObject.dynamicType’ instead”)
//{
// return [Son class];
//}

Father.m
//- (Class)class OBJC_SWIFT_UNAVAILABLE(“use ‘anObject.dynamicType’ instead”)
//{
// return [Father class];
//}

首先这道题,如果你想打印父类,那么就不应该这样写:

NSLog(@”%@”, NSStringFromClass([super class]));

而是:

NSLog(@”%@”,NSStringFromClass([self superclass]));

达到我们需要的结果后,我们就要思考,上面那段为什么会都输出Son呢,到底进行了什么?

首先前面说到过类似 [self class] 这种 会在运行时转换成 objc_msgSend 函数,objc_msgSend, 它就是负责发送一个消息给对象的C函数

objc-runtime.h 里面

#include

#include

objc_msgSend 和 objc_msgSendSuper 就是在message.h 类里

这个函数 objc_msgSend(<#id#>, <#SEL, …#>)
有两个参数

id objc_msgSend(id self, SEL op, …)
我们把 self 做为第一个参数传递进去。

id objc_msgSendSuper(struct objc_super *super, SEL op, …)

第一个参数是 objc_super 这样一个结构体,其定义如下:

struct objc_super {

__unsafe_unretained id receiver;

__unsafe_unretained Class super_class;

};

结构体有两个成员,第一个成员是 receiver, 类似于上面的 objc_msgSend函数第一个参数self 。第二个成员是记录当前类的父类是什么。

解惑:这个题目主要是考察关于objc中对 self 和 super 的理解。

self 是类的隐藏参数,指向当前调用方法的这个类的实例。

而 super 是一个 Magic Keyword, 它本质是一个编译器标示符,和 self 是指向的同一个消息接受者。

上面的例子不管调用[self class]还是[super class],接受消息的对象都是当前 Son *xxx 这个对象。而不同的是,super是告诉编译器,调用 class 这个方法时,要去父类的方法,而不是本类里的。

Class实际上是存在于内存中的,可以看成是一个特殊的对象 对一个子类发消息,如果子类中找不到对应的方法,会自动向上搜索,直到根类

[super class];在哪个类里写,哪个类就是接收消息的对象 self 指在本类中找到方法 让本类去执行 super 是在编译的时候 让机器去父类或者父类的父类找方法 然后还是本类执行 所以 【super class】 是在父类的父类 也就是NSObject中 找到了这个方法 但是 执行的时候 都是Son 执行的 所以 打印结果就是一样的(个人理解)

具体多看上面的连接,熟能生巧。

待补充