`

消息转发: 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];

 

分享到:
评论

相关推荐

    NSObject中methodSignatureForSelector、forwardInvocation两个消息方法

    在处理未知或未实现的消息时,`NSObject`提供了两个关键的方法:`methodSignatureForSelector:` 和 `forwardInvocation:`。这两个方法是Objective-C运行时系统的重要组成部分,对于理解和扩展动态语言的特性至关重要...

    IOS消息转发

    1. **捕获未声明的方法**:消息转发机制可以用于捕获那些在运行时添加的方法,确保程序的稳定性和兼容性。 2. **实现动态代理**:通过`forwardInvocation:`,可以实现动态代理,将消息转发给其他对象,提高代码复用...

    iOS消息转发机制在项目中的应用

    5. **消息转发**:接着,`- (void)forwardInvocation:(NSInvocation *)anInvocation`被调用,这里可以自定义消息的处理方式,比如记录日志、调用备用方法等。默认情况下,它会抛出一个未定义方法的异常。 二、项目...

    ios runtime消息转发机制

    除了上述流程,还可以利用`-methodSignatureForSelector:`方法获取消息的方法签名,这对于创建`NSInvocation`实例是必要的。此外,`NSInvocation`对象可以用来模拟调用其他方法,甚至可以将消息转发到其他类或者C...

    iOS消息转发机制及避免崩溃的解决方案.pdf

    如果快速转发失败,系统会调用`- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector`,获取方法的签名,然后调用`- (void)forwardInvocation:(NSInvocation *)anInvocation`。在这个阶段,我们有...

    ios-对象的消息转发机制.zip

    - **多态性扩展**:消息转发可以用来实现类似多重继承的效果,通过设置forwarding target,让一个对象能响应其他类的方法。 - **错误处理**:当对象接收到不期望的消息时,可以通过消息转发机制优雅地处理错误,而...

    iOS 最新面试总结题库,欢迎观看.docx

    3. 完整消息转发:如果以上两步都无法处理,Runtime会调用-methodSignatureForSelector:获取方法签名,然后创建NSInvocation对象并发送-forwardInvocation:消息,最后如果仍无法处理,会抛出未识别选择子...

    ios试题总结

    #### 三、伪继承:消息转发 Objective-C虽然不支持多继承,但提供了一种非常强大的机制——消息转发,来模拟多继承的行为。通过消息转发,我们可以让一个对象在运行时动态地响应不属于其自身类的消息。 ##### 1. ...

    runtime 消息发送和转发 动态创建类添加属性方法等

    如果返回`nil`,runtime会进入第二阶段转发,调用`- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector`获取方法签名,然后调用`- (void)forwardInvocation:(NSInvocation *)anInvocation`。...

    iOS runtime forwardInvocation详解及整理

    `forwardInvocation:`是Objective-C runtime 提供的一种消息转发机制,它为我们提供了处理未知或未实现方法的能力。当一个对象收到一个它无法响应的消息时,runtime 会尝试通过几个步骤来解决这个问题,`...

    iOS Runtime知识

    1. **`forwardInvocation:`** 当接收到未知的消息时,会触发该方法,可以在这里重定向到其他方法或对象。 2. **`methodSignatureForSelector:`** 用于获取或构建方法签名。 3. **`resolveInstanceMethod:`** 用于...

    iOS Runtime常见问题分析_周辉1

    8. **消息转发(Message Forwarding)**:当对象接收到无法处理的消息时,Runtime会启动消息转发机制,这包括`forwardInvocation:`和`methodSignatureForSelector:`方法,使得开发者有机会处理未定义的方法调用。...

    _objc_msgForward_demo

    _objc_msgForward_demo用来测试消息转发机制对象查找selector时,先查找cachelist,如果没有则查找methodlist,如果还没有就查找父类的methodlist都没有是还有三次机会可以处理这次selector访问1. + (BOOL)...

    objective-c运行时编程指南

    当接收到未知消息时,Objective-C对象可以通过一系列方法(如`forwardInvocation:`、`methodSignatureForSelector:`等)来处理这些消息,从而实现动态行为。 #### 类型编码与属性声明 - **类型编码**:Objective-C...

    面试题整理(优化后,需要持续优化)1

    - 当对象无法响应某个消息时,会依次通过`forwardInvocation:`、`methodSignatureForSelector:`、`forwardingTargetForSelector:`等步骤进行消息转发,最后可能会调用`objc_msgForward`函数。 11. **动态属性关联...

    iOS中Runtime的几种基本用法记录

    如果此方法返回`nil`,则进入第二步,`methodSignatureForSelector:`生成即将转发的方法签名,然后`forwardInvocation:`负责实际的转发。这是一个处理未知消息的强大机制,可以用来做错误处理或日志记录。 通过熟练...

Global site tag (gtag.js) - Google Analytics