@interfaceMyProxy :NSProxy{
id_innerObject;
}
+(instancetype)proxyWithObj:(id)Object;
@end
@interface Dog : NSObject
-(NSString*)barking:(NSInteger)months;
@end
@implementation MyProxy
+(instancetype)proxyWithObj:(id)Object{
MyProxy*proxy = [MyProxyalloc];
proxy->_innerObject= Object;
returnproxy;
}
-(NSMethodSignature*)methodSignatureForSelector:(SEL)sel{
return [_innerObject methodSignatureForSelector:sel];
}
-(void)forwardInvocation:(NSInvocation*)invocation{
if([_innerObjectrespondsToSelector:invocation.selector]) {
NSString*selectorName =NSStringFromSelector(invocation.selector);
NSLog(@"Befor calling %@",selectorName);
[invocationretainArguments];
NSMethodSignature*sig = [invocationmethodSignature];
//获取参数个数
NSUIntegercnt = [signumberOfArguments];
for(inti =0; i < cnt; i++) {
constchar* type = [siggetArgumentTypeAtIndex:i];
if(strcmp(type,"@") ==0) {
NSObject*obj;
[invocationgetArgument:&objatIndex:i];
NSLog(@"parameter (%d)'class is %@",i,[obj class]);
}elseif(strcmp(type,":") ==0){
SELsel;
[invocationgetArgument:&selatIndex:i];
//这里输出的是:"parameter (1) is barking:"
//也就是objc_msgSend的第二个参数
NSLog(@"parameter (%d) is %@",i,NSStringFromSelector(sel));
}elseif(strcmp(type,"q") ==0){
intarg =0;
[invocationgetArgument:&argatIndex:i];
//这里输出的是:"parameter (2) is int value is 4"
//稍后会看到我们再调用barking的时候传递的参数就是4
NSLog(@"parameter (%d) is int value is %d",i,arg);
}
}
//消息转发
[invocationinvokeWithTarget:_innerObject];
constchar*retType = [sigmethodReturnType];
if(strcmp(retType,"@") ==0){
NSObject*ret;
[invocationgetReturnValue:&ret];
//这里输出的是:"return value is wang wang!"
NSLog(@"return value is %@",ret);
}
NSLog(@"After calling %@",selectorName);
}
}
@end
```
@implementation Dog
-(NSString*)barking:(NSInteger)months{
return months > 3 ? @"wang wang!" : @"eng eng!";
}
@end
```