在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:`。这两个方法是Objective-C运行时系统的重要组成部分,对于理解和扩展动态语言的特性至关重要...
1. **捕获未声明的方法**:消息转发机制可以用于捕获那些在运行时添加的方法,确保程序的稳定性和兼容性。 2. **实现动态代理**:通过`forwardInvocation:`,可以实现动态代理,将消息转发给其他对象,提高代码复用...
5. **消息转发**:接着,`- (void)forwardInvocation:(NSInvocation *)anInvocation`被调用,这里可以自定义消息的处理方式,比如记录日志、调用备用方法等。默认情况下,它会抛出一个未定义方法的异常。 二、项目...
除了上述流程,还可以利用`-methodSignatureForSelector:`方法获取消息的方法签名,这对于创建`NSInvocation`实例是必要的。此外,`NSInvocation`对象可以用来模拟调用其他方法,甚至可以将消息转发到其他类或者C...
如果快速转发失败,系统会调用`- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector`,获取方法的签名,然后调用`- (void)forwardInvocation:(NSInvocation *)anInvocation`。在这个阶段,我们有...
- **多态性扩展**:消息转发可以用来实现类似多重继承的效果,通过设置forwarding target,让一个对象能响应其他类的方法。 - **错误处理**:当对象接收到不期望的消息时,可以通过消息转发机制优雅地处理错误,而...
3. 完整消息转发:如果以上两步都无法处理,Runtime会调用-methodSignatureForSelector:获取方法签名,然后创建NSInvocation对象并发送-forwardInvocation:消息,最后如果仍无法处理,会抛出未识别选择子...
#### 三、伪继承:消息转发 Objective-C虽然不支持多继承,但提供了一种非常强大的机制——消息转发,来模拟多继承的行为。通过消息转发,我们可以让一个对象在运行时动态地响应不属于其自身类的消息。 ##### 1. ...
如果返回`nil`,runtime会进入第二阶段转发,调用`- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector`获取方法签名,然后调用`- (void)forwardInvocation:(NSInvocation *)anInvocation`。...
`forwardInvocation:`是Objective-C runtime 提供的一种消息转发机制,它为我们提供了处理未知或未实现方法的能力。当一个对象收到一个它无法响应的消息时,runtime 会尝试通过几个步骤来解决这个问题,`...
1. **`forwardInvocation:`** 当接收到未知的消息时,会触发该方法,可以在这里重定向到其他方法或对象。 2. **`methodSignatureForSelector:`** 用于获取或构建方法签名。 3. **`resolveInstanceMethod:`** 用于...
8. **消息转发(Message Forwarding)**:当对象接收到无法处理的消息时,Runtime会启动消息转发机制,这包括`forwardInvocation:`和`methodSignatureForSelector:`方法,使得开发者有机会处理未定义的方法调用。...
_objc_msgForward_demo用来测试消息转发机制对象查找selector时,先查找cachelist,如果没有则查找methodlist,如果还没有就查找父类的methodlist都没有是还有三次机会可以处理这次selector访问1. + (BOOL)...
当接收到未知消息时,Objective-C对象可以通过一系列方法(如`forwardInvocation:`、`methodSignatureForSelector:`等)来处理这些消息,从而实现动态行为。 #### 类型编码与属性声明 - **类型编码**:Objective-C...
- 当对象无法响应某个消息时,会依次通过`forwardInvocation:`、`methodSignatureForSelector:`、`forwardingTargetForSelector:`等步骤进行消息转发,最后可能会调用`objc_msgForward`函数。 11. **动态属性关联...
如果此方法返回`nil`,则进入第二步,`methodSignatureForSelector:`生成即将转发的方法签名,然后`forwardInvocation:`负责实际的转发。这是一个处理未知消息的强大机制,可以用来做错误处理或日志记录。 通过熟练...