views:

70

answers:

1

How would I declare a class that has a method/message that takes a selector, stores the value of the selector, and then calls the selector later on?

ie if its called SomeObject it would be called like this:

-(id) init {
    // normal stuff here
    o = [[SomeObject alloc] init];
    return self;
}

-(void) checkSomething {
    [o checkSomethingWithResponse: @selector(answer:)]
}

-(void) answer: (int) value {
    NSLog(@"Check complete: %d", value);
}

(Sorry I know this might be an RTFM but I can't find any info myself)

+6  A: 

The SomeObject class needs a reference back to the object to be messaged.

This is pretty much exactly the delegate pattern; look that up for implementation details.

(Note that the delegate pattern generally allows all of the methods of the delegate to be optional. In this case, if -answer: is required, this is more like, say, UITableViewDataSource or NSTableView's data source. But the details of implementation are just like that of the delegate pattern, you just may not need to test to see if the object implements the method).

Or, assuming you really do want a target/selector (target/action, in Cocoa parlance) pair that you message with an integer value:

I would suggest redeclaring -answer: as:

- (void) answer: (NSNumber *) aValue;

This avoids the need to deal with a non-object argument.

IN your SomeObject class, you'd have something like:

[myAnswerer performSelector: myAnswererSelector withObject: [NSNumber numberWithInt: 1]];

And you might even declare myAnswerer and myAnswererSelector as:

@property(retain) MyAnswererClass *myAnswerer;
@property SEL myAnswererSelector;

Then use @synthesize in SomeObject's implementation to synthesize the setter/getter.

Note that on SnowLeopard, all of this can be solved much more elegantly with Blocks...

bbum