So, I bit the bullet and decided to create my own proxy class. In a subclass, you simply redefine the message "forwardInvocation:" and you call any code you need before calling [super forwardInvocation:] . Please, this will not work with vardic methods, since NSInvocation does not work with vardic methods.
#import <Foundation/Foundation.h> #import <objc/runtime.h> #import <objc/objc.h> #import <objc/message.h> @interface RJProxy : NSObject { @private NSObject *target; } @property(readwrite, retain) NSObject *target; -(NSObject *) getTarget; @end @implementation RJProxy @synthesize target; -(NSMethodSignature *) methodSignatureForSelector:(SEL)aSelector { if (objc_getAssociatedObject(self, "isProxy")) { IMP NSObjectImp = [NSObject instanceMethodForSelector:@selector(methodSignatureForSelector:)]; NSMethodSignature *methodSignature = (NSMethodSignature *) NSObjectImp(self, @selector(methodSignatureForSelector:), aSelector); if (methodSignature) return methodSignature; return [target methodSignatureForSelector:aSelector]; } else { Class subClass = self->isa; @try { self->isa = objc_getAssociatedObject(self, "realSuperclass"); return [super methodSignatureForSelector:aSelector]; } @finally { self->isa = subClass; } } } -(void) forwardInvocation:(NSInvocation *)anInvocation { if (objc_getAssociatedObject(self, "isProxy")) { Class subClass = target->isa; target->isa = objc_getAssociatedObject(self, "realSuperclass"); [anInvocation invokeWithTarget:target]; target->isa = subClass; } else { Class realSuperclass = objc_getAssociatedObject(self, "realSuperclass"); Class subclass = self->isa; self->isa = realSuperclass; if ([self respondsToSelector:[anInvocation selector]]) { [anInvocation invokeWithTarget:self]; } else { [self doesNotRecognizeSelector:[anInvocation selector]]; } self->isa = subclass; } } -(NSObject *) getTarget { if (objc_getAssociatedObject(self, "isProxy")) { return target; } return self; } @end BOOL object_setProxy(NSObject *object, RJProxy *proxy); BOOL object_setProxy(NSObject *object, RJProxy *proxy) { proxy.target = object; Class objectClass = object_getClass(object); Class objectSub = objc_allocateClassPair(objectClass, [[NSString stringWithFormat:@"%s_sub%i", class_getName(objectClass), objc_getAssociatedObject(objectClass, "subclassTimes")] UTF8String], 0); objc_setAssociatedObject(objectClass, "subclassTimes", (id) ((int) objc_getAssociatedObject(objectClass, "subclassTimes") + 1), OBJC_ASSOCIATION_ASSIGN); objc_registerClassPair(objectSub); Class proxyClass = object_getClass(proxy); Class proxySub = objc_allocateClassPair(proxyClass, [[NSString stringWithFormat:@"%s_sub%i", class_getName(proxyClass), objc_getAssociatedObject(proxyClass, "subclassTimes")] UTF8String], 0); objc_setAssociatedObject(proxyClass, "subclassTimes", (id) ((int) objc_getAssociatedObject(proxyClass, "subclassTimes") + 1), OBJC_ASSOCIATION_ASSIGN); objc_registerClassPair(proxySub); object_setClass(object, proxySub); object_setClass(proxy, proxySub); objc_setAssociatedObject(object, "isProxy", (id) NO, OBJC_ASSOCIATION_ASSIGN); objc_setAssociatedObject(proxy, "isProxy", (id) YES, OBJC_ASSOCIATION_ASSIGN); objc_setAssociatedObject(object, "realSuperclass", objectClass, OBJC_ASSOCIATION_ASSIGN); objc_setAssociatedObject(proxy, "realSuperclass", proxyClass, OBJC_ASSOCIATION_ASSIGN); return NO; } @interface SynchronizeProxy : RJProxy @end @implementation SynchronizeProxy -(void) forwardInvocation:(NSInvocation *)anInvocation { @synchronized ([self getTarget]) { [super forwardInvocation:anInvocation]; } } @end int main (int argc, const char * argv[]) { @autoreleasepool { NSArray *arrayToSynchronize = [NSArray arrayWithObjects:@"This, is, a, test!", nil]; SynchronizeProxy *myProxy = [SynchronizeProxy new]; object_setProxy(arrayToSynchronize, myProxy); // now all calls will be synchronized! NSLog(@"Array at address 0x%X with count of %lu, and Objects %@ ", (unsigned) arrayToSynchronize, [arrayToSynchronize count], arrayToSynchronize); [myProxy release]; [arrayToSynchronize release]; } return 0; }