views:

299

answers:

2

I have a function that creates a UIView with a bunch of UIButtons.

Each button calls a function with a string for a parameter.

So, in my function I do something like:

[button addTarget: [multiRadio objectAtIndex:0]
           action: NSSelectorFromString([multiRadio objectAtIndex:1])
 forControlEvents:UIControlEventTouchUpInside];

However, this bit of code doesn't specify the string parameter that the action needs to get passed.

If I have that string parameter in [multiRadio objectAtIndex:2], how do I set the button's actions to use the string?

+1  A: 

Why not just access it directly from the method you call? Instead of this:

- ( void )someMethod:( id )sender withString:( NSString * )string {
    [ self doSomethingWithString:string ];
}

use this:

- ( void )someMethod:( id )sender {
    SomeClass *multiRadio = [[ SomeClass alloc ] init ];
    [ self doSomethingWithString:[ multiRadio objectAtIndex:2 ]];
    ...
    [ multiRadio release ];
}

Change the method signatures as necessary, obviously, but that’s one way around it.

Jeff Kelley
Either the design should be reconsidered or the posters suggestion taken.From http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ActionMessages/Concepts/TargetsAndActions.html#//apple_ref/doc/uid/20000427An action method takes only one argument: the sender. The sender may be either the NSControl that sends the action message or, on occasion, another object that the target should treat as the sender. When it receives an action message, a target can return messages to the sender requesting additional information about its status.
nall
A: 

I'd create an object class to act as the receiver for these events. Something like this:

ActionWrangler *wrangler = [[ActionWrangler alloc] init];
wrangler.target = [multiRadio objectAtIndex:0];
wrangler.selector = NSSelectorFromString([multiRadio objectAtIndex:1]);
wrangler.argument = [multiRadio objectAtIndex:2];
[button addTarget:wrangler
           action:@selector(wrangle)
 forControlEvents:UIControlEventTouchUpInside];

And then ActionWranger would have a wrangle method like so:

- (void)wrangle
{
    [target performSelector:selector withObject:argument];
}

Your biggest issue then would be tracking the ActionWrangler instances so you can release them.

Benno