消息转发: methodSignatureForSelector + forwardInvocation

      在object-C中,我们可以向一个实例发送消息,这类似于其他编程语法中的方法调用,实例收到消息后,会进行一些处理:例如实例收到消息后,如果能respondsToSelector,那么就调用相应的方法,如果不能response一般情况会crash。下面通过方面减少这种crash。

     

      实例收到消息后,一般的处理流程如下:

      1,发送消息,如[obj methodB];

      2,系统会检查是否能response这个消息

      3,如果能response则调用相应方法,不能则抛出异常。

 

      第三步中,默认抛出异常,通过重新NSObject的方法methodSignatureForSelector和forwardInvocation能够在实例不response这个消息时,将消息交由其他类实例进行处理,减少crash的几率。当检测到实例不能相应对应的消息时,系统会发出methodSignatureForSelector消息,询问这个消息是否有效,有效就返回方法签名之类的信息,无效返回nil(返回nil抛出异常);如果不是nil,接下来会发送forwardInvocation消息,我们能够在forwardInvocation消息中将消息委托给其他类实例进行处理。以下用代码进行说明:

ObjA.h

@interface ObjA
@end

ObjA.m

#import "ObjA.h"
#import "ObjB.h"

@implementation ObjA
{
      ObjB   *_b;
}

- (void)dealloc
{
      [_b release], _b = nil;
      
      [super dealloc];
}

- (id)init
{
      self = [super init];
      if ( self ) {
           _b = [[ObjB alloc] init];
      }
      return self;
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
      NSMethodSignature *signature = [super methodSignatureForSelector:aSelector];
      if ( !signature ) {
            signature = [_b methodSignatureForSelector:aSelector];
      }
      return signature;
}

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
      if ( [_b respondsToSelector:[anInvocation selector]] ) {
            [anInvocation invokeWithTarget:_b];
      } else {
            [super forwardInvocation:anInvocation];
      }
}

ObjB.h

@interface ObjB
- (void)methodB;
@end

 

ObjB.m

#import "ObjB.h"

@implementation ObjB

- (void)methodB
{
      NSLog(@"methodB");
}

@end

 

 调用代码:

[objA methodB];
// [objA performSelector:@selector(methodB) withObject:nil];

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值