iOS学习记录iOS 开发 深入浅出iOS

runtime中的消息转发

2016-04-05  本文已影响147人  我系哆啦

一直以来,都知道object-c是支持消息转发的,也就是说它可以使一个类响应另外一个类中实现的消息(方法)。到底具体动态转发具体的过程是怎么样的.用代码说话.通过比较普通的方法调用和通过消息转发的方法调用来一探究竟.下面新建个简单的car类.


<pre>
@interface Car : NSObject

<pre>
@implementation Car
-(instancetype)init{
self = [super init];
if (self) {
_carInfo = @"This Is A Car";
}
return self;
}
+(instancetype)car{
return [[self alloc] init];
}
@end
</pre>

普通的方法调用

<pre>
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
Car *myCar = [Car car];
NSString * upperStr = [(NSString *)myCar uppercaseString];
NSLog(@"%@--%@",myCar.carInfo,upperStr);
}
</pre>

未实现消息转发功能的方法调用结果

实现消息转发功能的方法调用

在给程序添加消息转发功能以前,必须覆盖两个方法,即methodSignatureForSelector: 和 forwardInvocation:。

在Car.m文件中重写上面两个方法

<pre>
//采用迭代的方式为当前被调用的方法创建一个有效的签名
-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
NSMethodSignature *signature = [super methodSignatureForSelector:aSelector];
if (!signature) {
signature = [self.carInfo methodSignatureForSelector:aSelector];
}
return signature;
}
//得到签名后,转入forwardInvocation:方法对其调用的方法(UTF8String)进行实现.
-(void)forwardInvocation:(NSInvocation *)anInvocation{
SEL aSelector = [anInvocation selector];
if ([self.carInfo respondsToSelector:aSelector]) {
[anInvocation invokeWithTarget:self.carInfo];
}
}
</pre>
同样调用方法:
<pre>
-(void)touchesBegan:(NSSet<UITouch *> )touches withEvent:(UIEvent )event{
Car *myCar = [Car car];
NSString *upperStr = [(NSString *)myCar uppercaseString];
NSLog(@"%@--%@",myCar.carInfo,upperStr);
}
</pre>
神奇的事情发生了:

实现消息转发功能的方法调用结果
上一篇 下一篇

猜你喜欢

热点阅读