, NSObject forwardInvocation: NSInvocation, . NSInvocation invokeWithTarget:, , .
fowardInvocation:, , , methodSignatureForSelector:, NSInvocation.
, forwardInvocation :
@implementation Forwarder
@synthesize friendObject;
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
return [self.friendObject methodSignatureForSelector:aSelector];
}
- (void)forwardInvocation:(NSInvocation *)anInvocation {
NSLog("Forwarding method: %@", [anInvocation selector]);
NSMethodSignature *sig = [anInvocation methodSignature];
int numberOfArgs = [[anInvocation methodSignature] numberOfArguments];
id objPointer;
NSMutableArray *argArray = [NSMutableArray array];
for (int i = 2; i < numberOfArgs; i++) {
[anInvocation getArgument:&objPointer atIndex:i];
[argArray addObject:objPointer];
}
}
@end
, . , , , C. NSMethodSignature getArgumentTypeAtIndex:, , . size_t malloc/calloc.
: , // Get the juicy info in methodSignature , , , .
( Apple NSMethodSignature signatureWithObjCTypes:.)
Edit2: , ( ) , , , , JavaScript.
, Forwarder .
@protocol ForwarderDelegate <NSObject>
- (void)selectorCalled:(SEL)selector withArguments:(NSArray *)args;
@end
:
@interface Forwarder : NSObject {
@private
NSObject *interfaceObject;
id<ForwarderDelegate> delegate;
}
@property (nonatomic, retain) NSObject *interfaceObject;
@property (nonatomic, retain) id<ForwarderDelegate> delegate;
@end
@implementation Forwarder
@synthesize interfaceObject;
@synthesize delegate;
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
return [interfaceObject methodSignatureForSelector:selector];
}
- (void)forwardInvocation:(NSInvocation *)anInvocation {
int numberOfArgs = [[anInvocation methodSignature] numberOfArguments];
NSMutableArray *args = [NSMutableArray array];
id ref;
for (int i = 2; i < numberOfArgs; i++) {
[anInvocation getArgument:&ref atIndex:i];
[args addObject:ref];
}
if ([self.interfaceObject respondsToSelector:[anInvocation selector]]) {
[anInvocation invokeWithTarget:self.interfaceObject];
}
[self.delegate selectorCalled:[anInvocation selector] withArguments:args];
}
@end
, . , - , :
@interface testreflectAppDelegate : NSObject <UIApplicationDelegate, ForwarderDelegate> {
UIWindow *window;
}
@end
@implementation testreflectAppDelegate
@synthesize window;
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[window makeKeyAndVisible];
Forwarder *forwarder = [[[Forwarder alloc] init] autorelease];
forwarder.delegate = self;
forwarder.interfaceObject = self;
[((id)forwarder) doFoo:[NSNumber numberWithInt:1]
withBar:[NSNumber numberWithInt:2]];
return YES;
}
- (void)doFoo:(NSNumber *)foo withBar:(NSNumber *)bar {
NSLog(@"doFoo:withBar: called. Args: %d %d", [foo intValue], [bar intValue]);
}
- (void)doFoo:(NSNumber *)foo {
NSLog(@"doFoo called. Args: %d", [foo intValue]);
}
- (void)selectorCalled:(SEL)selector withArguments:(NSArray *)args {
NSLog(@"selectorCalled: %s with %d arguments", selector, [args count]);
[self doFoo:[args objectAtIndex:0]];
}
@end
- :
testreflect[3098:207] doFoo:withBar: called. Args: 1 2
testreflect[3098:207] selectorCalled: doFoo:withBar: with 2 arguments
testreflect[3098:207] doFoo called. Args: 1
. , TypeEncodings.