Is there a way to pass the entire list of arguments to another method in Objective-C?

I would like to pass all the arguments received in my method to another method as much as possible.

Ideally, this will be done by passing a dictionary or some system variable (similar to _cmd).

In other words, I'm looking for something like an array argumentsin javascript or something giving me access to the argument list that is currently called.

+3
source share
2 answers

, 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];

    // Get the juicy argument list info from [anInvocation methodSignature]
    // NOTE: Arguments 0 and 1 are for self and _cmd So we'll skip those.

    int numberOfArgs = [[anInvocation methodSignature] numberOfArguments];

    // Assuming all arguments are objects.
    id objPointer;
    NSMutableArray *argArray = [NSMutableArray array];

    for (int i = 2; i < numberOfArgs; i++) {
        [anInvocation getArgument:&objPointer atIndex:i];
        [argArray addObject:objPointer];
    }

    // Now argArray contains the array of all the arguments.
}

@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;
}

// Some object whose methods we want to respond to.
@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];
    }

    // Call the method on the interface (original) object.
    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.

+4

NSMethodSignature. ​​ .

+1

Source: https://habr.com/ru/post/1788160/


All Articles