ios没有直接的多重继承的实现机制,但可以从其他方面来实现类似的效果。
方式一:
采用组合、聚合的方式,比较常见。
方式二:
采用Runtime的机制,进行代理和消息分发的处理。下面阐述下以下实现方式:
1. 子类继承自NSProxy。这里定义了个基类来实现:
#import
NS_ASSUME_NONNULL_BEGIN
/*
作者:jolly
类名:BaseProxy
作用描述:代理类的基类,可以实现多继承自多个target的方法和变量
*/
@interface BaseProxy :NSProxy
/*
作者:jolly
函数名:init
功能说明:初始化方法
入参描述:
返回值描述: BaseProxy对象
*/
- (instancetype)init;
- (void)addTarget:(id)target; //添加当个被继承的对象。
- (void)addTargets:(NSArray*)targets; //添加多个被继承的对象
- (void)removeTarget:(id)target; //移除被代理对象
- (void)removeAll; //移除所有的被代理对象
/*
作者:jolly
函数名:methodNotFound
功能说明:在runtime没有找到对应的selector的时候,触发该方法的调用,代理类无响应具体的selector时触发下面的回调。
*/
- (void)methodNotFound:(SEL)aSeletor;
@end
NS_ASSUME_NONNULL_END
实现方式,
//步骤1,方法实现方法签名的映射
- (NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector
{
NSMethodSignature * sg = nil;
for(id delegate in self.targets) {
sg = [delegate methodSignatureForSelector:aSelector];
if(sg !=nil) {
break;
}
}
returnsg;
}
//若此处没有找到对应的转发处理,则报出unrecognized selector sent to instance错误。
//步骤2 1对多转发
- (void)forwardInvocation:(NSInvocation*)anInvocation
{
NSLog(@"forwardInvocation ==== [%@]",anInvocation);
for(idtargetinself.targets) {
[anInvocationinvokeWithTarget:target];
}
}
- (void)doesNotRecognizeSelector:(SEL)aSelector
{
[selfmethodNotFound:aSelector];
}
- (void)methodNotFound:(SEL)aSeletor
{
NSLog(@"methodNotFound ==== [%@]",NSStringFromSelector(aSeletor));
}
以上是代理类的基类的实现。
接下来,真正的实现类的处理步骤。
A. 定义被继承的协议接口等。本例如下:
//公共协议
@protocol ObjAProto
@property(nonatomic,copy)NSString * userName;
- (void)hello:(NSString*)name;
@end
B. 实际代理类的实现:
@interface ObjProxy : BaseProxy
@end
@implementation ObjProxy
-(void)methodNotFound:(SEL)aSeletor //未找到相应的代理方法,而触发的回调。
{}
@end
C. 实际被代理的类的实现:
@interface ObjA : NSObject
@end
@implementation ObjA
- (void)hello:(NSString*)name
{
NSLog(@"%@", [@"hi jolly,that's mime " stringByAppendingString:name]);
}
- (NSString*)userName
{
return @"jolly.wu";
}
@synthesize userName;
@end
D. main函数的调用方式:
ObjProxy * py = [[ObjProxy alloc] init];
[py addTarget:[ObjA new]];
[py hello:@"jon"]; //实则调用ObjA实例里面的方法。
以上就是整体的多重继承的实现方式原理。注意代理类中若实现了被代理对象的方法相当于实现了消息的拦截,则不会触发消息转换流程,也就不会走到proxy里面的具体代理调用了。具体的可以参照https://github.com/jolly-wu/XibInHerit的实现。