Skip navigation.
 
mltransparent proxy using forwardInvocation, how?
FROM : Simon Strandgaard
DATE : Sat Aug 26 11:23:33 2006

Hi list,

How does one make a transparent proxy?
I hope to intercept all messages going through it, so that I can
debug my custom NSCell.  Is this possible at all?


I have made an incomplete attempt at this below
and I would like to hear your thoughts about it.
Should one inherit from NSObject or NSProxy ?
Which methods to overload ?



regards
Simon Strandgaard



// main.mm
#include <Foundation/Foundation.h>

@interface TransparentProxy : NSObject {
   id _proxied_object;
}
@end

@implementation TransparentProxy

-(id)initWithProxiedObject:(id)object {
    self = [super init];
   if(self) {
       NSLog(@"[proxy.init]\n");
       _proxied_object = object;
   }
   return self;
}

-(NSMethodSignature*)methodSignatureForSelector:(SEL)sel {
   NSLog(@"[proxy.msfs] methodSignatureForSelector \"%@\"\n",
       NSStringFromSelector(sel));
   
   NSMethodSignature* sig = nil;
   sig = [_proxied_object methodSignatureForSelector:sel];
   if(sig) {
       NSLog(@"[proxy.msfs] recognized by proxied_object\n");
       return sig;
   }

   sig = [super methodSignatureForSelector:sel];
   if(sig) {
       NSLog(@"[proxy.msfs] recognized by super\n");
       return sig;
   }

   sig = [NSObject methodSignatureForSelector:@selector(self)];
   NSLog(@"[proxy.msfs] ERROR: selector not recognized, absorbing!\n");
   return sig;
}

-(void)forwardInvocation:(NSInvocation*)inv {
   SEL sel = [inv selector];
   NSLog(@"[proxy.fi] forwardInvocation \"%@\"\n",
       NSStringFromSelector(sel));
       
   if([_proxied_object respondsToSelector:sel]) {
       NSLog(@"[proxy.fi] invoking with proxy\n");
       [inv invokeWithTarget:_proxied_object];
       return;
   }
   if([self respondsToSelector:sel]) {
       NSLog(@"[proxy.fi] invoking with self\n");
       [inv invokeWithTarget:self];
       return;
   }
   NSLog(@"[proxy.fi] ERROR: absorbing!\n");
}

-(BOOL)respondsToSelector:(SEL)sel {
   NSLog(@"[proxy.rts] respondsToSelector \"%@\"\n",
       NSStringFromSelector(sel));
   return [_proxied_object respondsToSelector:sel];
}

-(NSString*)description {
   NSLog(@"[proxy.description]\n");
   return [_proxied_object description];
}

-(Class)class {
   NSLog(@"[proxy.class]\n");
   return [_proxied_object class];
}

-(Class)superclass {
   NSLog(@"[proxy.superclass]\n");
   return [_proxied_object superclass];
}

-(BOOL)isKindOfClass:(Class)aClass {
   NSLog(@"[proxy.ikoc]\n");
   return [_proxied_object isKindOfClass:aClass];
}
@end

int main(int argc, char *argv[]) {
   NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

   NSNumber* num = [[NSNumber alloc] initWithInt:42];
   id obj = [[TransparentProxy alloc] initWithProxiedObject:num];
   NSLog(@"---------------\n");
   
   NSLog(@"[obj xintValue]\n");
   int i = [obj xintValue];
   NSLog(@"i=%i\n", i);
   NSLog(@"---------------\n");
   
   NSLog(@"[obj setValue:5]\n");
   [obj setValue:5];
   NSLog(@"---------------\n");

   NSLog(@"[obj intValue]\n");
   int j = [obj intValue];
   NSLog(@"j=%i\n", j);
   NSLog(@"---------------\n");
   
   NSLog(@"instance=%@\n", obj);
   NSLog(@"---------------\n");

   NSLog(@"class=%@\n", [obj class]);
   NSLog(@"---------------\n");

   NSLog(@"superclass=%@\n", [obj superclass]);
   NSLog(@"---------------\n");
   
   NSLog(@"[obj self]\n");
   NSLog(@"self=%@\n", [obj self]);
   NSLog(@"---------------\n");
   
   NSLog(@"[obj respondsToSelector:@selector(dontUnderstand)];\n");
   [obj respondsToSelector:@selector(dontUnderstand)];
   NSLog(@"---------------\n");

   NSLog(@"[obj performSelector:@selector(dontUnderstand)];\n");
   [obj performSelector:@selector(dontUnderstand)];
   NSLog(@"---------------\n");
   
   NSLog(@"[obj isKindOfClass: [NSCell class]];\n");
   BOOL b1 = [obj isKindOfClass: [NSCell class]];
   NSLog(@"is same: %s\n", (b1 ? "yes" : "no"));
   NSLog(@"---------------\n");

   NSLog(@"[obj isKindOfClass: [NSNumber class]];\n");
   BOOL b2 = [obj isKindOfClass: [NSNumber class]];
   NSLog(@"is same: %s\n", (b2 ? "yes" : "no"));
   NSLog(@"---------------\n");
   
   return 0;
}

Related mailsAuthorDate
mltransparent proxy using forwardInvocation, how? Simon Strandgaard Aug 26, 11:23
mlRe: transparent proxy using forwardInvocation, how? Nick Zitzmann Aug 26, 19:28
mlRe: Re: transparent proxy using forwardInvocation, how? Julien Jalon Aug 26, 19:33
mlRe: Re: transparent proxy using forwardInvocation, how? Simon Strandgaard Aug 26, 19:57