Objective-C runtime之消息转发机制(三)

原创 2013年03月02日 16:58:37

Objective-C runtime之消息转发机制(三)

作者:wangzz
转载请注明出处
如果觉得文章对你有所帮助,请通过留言或关注微信公众帐号wangzzstrive来支持我,谢谢!

学了那么久的Objective-C,给我的感觉就是它什么都是动态的,你将会听到一个新的名词:

一、动态方法解析

1、+(BOOL) resolveInstanceMethod:(SEL) sel

这是NSObject根类提供的类方法,调用时机为当被调用的方法实现部分没有找到,而消息转发机制启动之前的这个中间时刻。

2、@dynamic关键字

Objective-C2.0 提供了@dynamic关键字。这个关键字有两个作用:

①告诉编译器不要创建实现属性所用的实例变量;

②告诉编译器不要创建该属性的get和setter方法。

如果我们在@interface接口文件中声明了一个属性,如下所示:

@property(nonatomic,retain) NSString    *name;

默认情况下,编译器会为当前类自动生成一个NSString   *_name的实例变量(如果想改变实例变量的名称可以用@synthesize关键字),同时会生成两个名为- (NSString *)name和- (void)setName:(NSString *)aName的存取方法。

@dynamic关键字就是告诉编译器不要做这些事,同时在使用了存取方法时也不要报错,即让编译器相信存取方法会在运行时找到。

比如在@implementation文件中做了如下声明:

@dynamic name;
如果使用了name属性的setter方法,又不想在运行时崩溃,就可以在运行时做点动作:

void dynamicMethodIMP(id self, SEL _cmd)
{
    // implementation ....
}

+ (BOOL)resolveInstanceMethod:(SEL)sel
{
    NSLog(@"sel is %@", NSStringFromSelector(sel));
    if(sel == @selector(setName:)){
        class_addMethod([self class],sel,(IMP)dynamicMethodIMP,"v@:");
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}

在resolveInstanceMethod的实现中,我们通过class_addMethod方法动态的向当前对象增加了dynamicMethodIMP函数,来代替-(void)setName:(NSString *)name的实现部分,从而达到了动态生成name属性方法的目的。

值得说明的是:

在上个例子中,我们自己实现了-(void)setName:(NSString *)name方法,则在运行的时候,调用完我们实现的-(void)setName:(NSString *)name方法后,运行时系统仍然会调+(BOOL) resolveInstanceMethod:(SEL) sel方法,只不过这里的sel会变成_doZombieMe,从而我们实现重定向的if分支就进不去了,即我们实现的方法不会被覆盖。

②"v@:"属于Objective-C类型编码的内容,感兴趣的同学可以自己google一下。

二、runtime system消息转发机制

对象是谦恭的,它会接收所有发送过来的消息,哪怕这些消息自己无法响应。问题来了:当对象无法响应这些消息时怎么办?runtime提供了消息转发机制来处理该问题。

当外部调用的某个方法对象没有实现,而且resolveInstanceMethod方法中也没有做重定向处理时,就会触发- (void)forwardInvocation:(NSInvocation *)anInvocation方法。在该方法中,可以实现对不能处理的消息做的一些默认处理,也可以以其它的某种方式来避免错误被抛出。像forwardInvocation:的名字一样,这个方法通常用来将不能处理的消息转发给其它的对象。通常我们重写该方法的方式如下所示:

-(void)forwardInvocation:(NSInvocation *)invocation
{
	SEL invSEL = invocation.selector;
	if ([someOtherObject respondsToSelector:invSEL])
		[anInvocation invokeWithTarget:someOtherObject];
	} else {
		[self doesNotRecognizeSelector:invSEL]; 
	}                                                                          
}

怎么看着有点像多继承呀???你说对了,消息转发提供了多重继承的很多特性。然而,两者有很大的不同:多重继承是将不同的行为封装到单个的对象中,有可能导致庞大的,复杂的对象。而消息转发是将问题分解到更小的对象中,但是又以一种对消息发送对象来说完全透明的方式将这些对象联系起来。总之,Objective-C通过这种方式,一定程度上减小了自己不支持多继承的劣势。


经过半个月的时间,自己总结、整理出了这三篇文章,到这里,对Objective-C运行时的学习算是告一段落了。文笔的原因,文章结构不是很清晰,还请见谅。对运行时理解不到位,或者是有错误的地方,还请广大博友指出,感激不尽!


iOS Runtime详解(消息机制,类元对象,缓存机制,消息转发)

原创Blog,转载请注明出处 http://blog.csdn.net/hello_hwc?viewmode=list 我的stackoverflow前言:之前一篇文章里,我详细的讲解了一些基...
  • Hello_Hwc
  • Hello_Hwc
  • 2015年11月09日 15:02
  • 4576

iOS runtime探究(二): 从runtime开始深入理解OC消息转发机制

你要知道的runtime都在这里转载请注明出处 http://www.jianshu.com/p/eac6ed137e06本文主要讲解runtime相关知识,从原理到实践,由于包含内容过多分为以下五篇...
  • u014205968
  • u014205968
  • 2017年03月28日 17:17
  • 1481

Objective-C 消息发送与转发机制原理

原文地址:http://yulingtianxia.com/blog/2016/06/15/Objective-C-Message-Sending-and-Forwarding/#源码解析 消息发送...
  • wangweijjj
  • wangweijjj
  • 2016年07月12日 14:31
  • 2422

IOS动态方法决议

首先,笔者想通过下面一段代码来解释什么是动态方法决议,动态方法决议能做什么。 @interface AA : NSObject - (void)out; - (void)say:(NSStrin...
  • snmhm1991
  • snmhm1991
  • 2014年08月11日 11:55
  • 2948

Objective-C runtime之消息转发机制(三)

学了那么久的Objective-C,给我的感觉就是它什么都是动态的,你将会听到一个新的名词: 一、动态方法解析 1、+(BOOL) resolveInstanceMethod:(SEL) sel 这是...
  • wzzvictory_tjsd
  • wzzvictory_tjsd
  • 2013年03月02日 16:58
  • 13734

OC学习Runtime之消息传递,消息转发机制

坚持 成长 每日一篇
  • u014410695
  • u014410695
  • 2015年09月22日 10:48
  • 2139

Objective-C Runtime(三)消息转发机制

消息转发机制概述 上一篇博客《消息传递机制》中讲解了Objective-C中对象的消息传递机制。本文需要讲解另外一个重要问题:当对象收到无法处理的消息会发生什么? 显然,若想让类能理解某条...
  • xsh841272293
  • xsh841272293
  • 2017年09月19日 10:03
  • 230

[深入浅出Cocoa]之消息(二)-详解动态方法决议(Dynamic Method Resolution)

[深入浅出Cocoa]之消息(二)-详解动态方法决议(Dynamic Method Resolution) 罗朝辉 (http://blog.csdn.net/kesalin/) 本文遵循...
  • kesalin
  • kesalin
  • 2012年11月14日 23:39
  • 7424

说说objcRuntime的一些妙用(class_addMethod,class_replaceMethod)

前言:陈列一下今天要讲的知识点:objc_addMethod,objc_replaceMethod,method_getImplementation,object_getClass 涉及到的知识 》》...
  • Poppin_Category
  • Poppin_Category
  • 2015年10月29日 16:02
  • 2679

Objective-C runtime之消息转发机制(三)

原帖地址:http://blog.csdn.net/wzzvictory/article/details/8629036 学了那么久的Objective-C,给我的感觉就是它什么都是动态的,你将...
  • fewname
  • fewname
  • 2013年08月27日 10:49
  • 341
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Objective-C runtime之消息转发机制(三)
举报原因:
原因补充:

(最多只允许输入30个字)