classA 实现了methodA 方法 classB 实现了 methodB 方法 classC 要同时实现methodA和methodB方法 在C++ 中用多继承就能实现,但是Objective c 不支持多重继承,那如何实现。
方法1. 组合方式,用ClassC 添加ClassA ,ClassB成员变量 来调用methodA,methodB
//定义ClassA以及其methodA
@interface ClassA : NSObject {
}
-(void)methodA;
@end
//定义ClassB以及其methodB
@interface ClassB : NSObject {
}
-(void)methodB;
@end
//定义ClassC以及其需要的methodA,methodB
@interface ClassC : NSObject {
ClassA *a;
ClassB *b;
}
-(id)initWithA:(ClassA *)A b:(ClassB *)B;
-(void)methodA;
-(void)methodB;
@end
//注意在ClassC的实现
@implementation ClassC
-(id)initWithA:(ClassA *)A b:(ClassB *)B{
a=[[ClassA alloc] initWithClassA: A];//[A copy];
b=[[ClassB alloc] initWithClassB: B];//[B copy];
}
-(void)methodA{
[a methodA];
}
-(void)methodB{
[b methodB];
}
方法2.协议protocol 设置ClassA delegate和 ClasssB delegate 以及实现方法ClassA里的methodA,和ClasssB里的methodB。ClassC遵守这两个协议就可以。
方法3.类别 ClassC的类别 可以实现ClassA的methodA和ClassB的methodB两个方法,这样ClassC就可以调用methodA和methodB
方法4.消息转发机制
我们知道objective-c中调用方法的方式是发消息,那如果给一个实例对象发一个未定义的消息呢?结果就是crash,其实这中间系统给我们第二次机会,就是可以转发该消息
如果未调到定义的消息,runtime会给该实例第二次机会,首先调用methodSignatureForSelector 或去方法签名,然后调用forwardInvocation,如果用户自己定义的类,没有重写这两个方法,即不支持方法转发
- @interface LOCBird : NSObject {
- NSString* name_;
- }
- @end
- @implementation LOCBird
- - (id)init
- {
- self = [super init];
- if (self) {
- name_ = [[NSString alloc] initWithString:@"I am a Bird!!"];
- }
- return self;
- }
- - (void)dealloc
- {
- [name_ release];
- [super dealloc];
- }
- - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
- {
- NSMethodSignature* signature = [super methodSignatureForSelector:aSelector];
- if (signature==nil) {
- signature = [name_ methodSignatureForSelector:aSelector];
- }
- NSUInteger argCount = [signature numberOfArguments];
- for (NSInteger i=0 ; i<argCount ; i++) {
- NSLog(@"%s" , [signature getArgumentTypeAtIndex:i]);
- }
- NSLog(@"returnType:%s ,returnLen:%d" , [signature methodReturnType] , [signature methodReturnLength]);
- NSLog(@"signature:%@" , signature);
- return signature;
- }
- - (void)forwardInvocation:(NSInvocation *)anInvocation
- {
- NSLog(@"forwardInvocation:%@" , anInvocation);
- SEL seletor = [anInvocation selector];
- if ([name_ respondsToSelector:seletor]) {
- [anInvocation invokeWithTarget:name_];
- }
- }
- @end
多继承消息转发原理就是 ClassC 没法实现methodA 和methodB 但是有成员变量ClassA 实力和ClassB实例。可以在用ClassC调用methodA 和methodB方法的时候消息转发给对应的实例就不会导致crash。其实和1组合方式类似。
主要参考链接:
http://blog.youkuaiyun.com/freshforiphone/article/details/7381329
有不对地方欢迎指出