在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];