它来实现一下"伪多继承".
直接上个代码来展示下
#import <Foundation/Foundation.h>
@interface JanProxy : NSProxy
- (void)transformObjc:(NSObject *)objc;
@end
JanProxy.m
#import "JanProxy.h"
@interface JanProxy ()
@property(nonatomic,strong)NSObject *objc;
@end
@implementation JanProxy
- (void)transformObjc:(NSObject *)objc
{
//复制对象
self.objc = objc;
}
//2.有了方法签名之后就会调用方法实现
- (void)forwardInvocation:(NSInvocation *)invocation
{
if (self.objc) {
//拦截方法的执行者为复制的对象
[invocation setTarget:self.objc];
if ([self.objc isKindOfClass:[NSClassFromString(@"Teacher") class]]) {
//拦截参数 Argument:表示的是方法的参数 index:表示的是方法参数的下标
NSString *str = @"拦截消息";
[invocation setArgument:&str atIndex:2];
}
//开始调用方法
[invocation invoke];
}
}
//1.查询该方法的方法签名
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
{
NSMethodSignature *signature = nil;
if ([self.objc methodSignatureForSelector:sel]) {
signature = [self.objc methodSignatureForSelector:sel];
}
else
{
signature = [super methodSignatureForSelector:sel];
}
return signature;
}
@end
使用方法
Dog *dog = [[Dog alloc]init];
//OC中方法的调用本质上是给这个对象发送一个消息
Cat *cat = [[Cat alloc] init];
//开始复制拦截方法
JanProxy *proxy = [JanProxy alloc];
//开始变身成猫
[proxy transformObjc:cat];
//开始调猫的方法
[proxy performSelector:@selector(eat:) withObject:@"猫发出消息"];
//开始变身成狗
[proxy transformObjc:Dog];
//开始调用学生的方法
[proxy performSelector:@selector(shut)];
最后的结果
image
控制台输出结果 发现没有,猫发出消息已经被子类的内部拦截并且做出了修改.
总结
OC中存在这么一个默默无闻的类NSProxy,填补了"多继承"这个空白区.
网友评论