CodeGuy
CodeGuy

Reputation: 28905

Passing along Methods - Objective-C

I'm fairly new to Objective-C, and it would be really helpful if someone could help me with the following task:

I have a class TheController that has a method DoTask. The goal of DoTask is to reach out to a MasterUtility (also a custom made class) and get Data, and then send it back when it is done (it uses a thread). Specifically, I want it to send it to dataReceiver in ReportsViewController. I think I need to use @selector or something like that. Here is some code:

@implementation ReportsViewController

-(void)doTask {
     MasterUtilities *mu = [[MasterUtilities alloc] init];
     [mu getDataAndSendTo:[WHAT GOES HERE]]
}

-(void)dataReceiver:(NSArray *)data {
    NSLog(@"data: %@",data);
}

@end

Here is MasterUtilities

    @implementation MasterUtilities

   - (void)getDataAndSendTo:[WHAT GOES HERE] {
        NSArray *data = [[NSArray init] alloc];
        ....getting data here....

        [WHAT GOES HERE? HOW DO I CALL THE METHOD (dataReceiver) IN ReportsViewController?]
     }

     @end

Can anyone fill in the areas that indicate "WHAT GOES HERE"? Thank you!!



Upvotes: 0

Views: 638

Answers (3)

zoul
zoul

Reputation: 104145

You could use a block:

typedef void (^Callback)(NSArray*);

[somebody doSomethingAndPerform:^(NSArray *data) {
    // do whatever you want with the data
}];

- (void) doSomethingAndPerform: (Callback) callback
{
    NSArray *data = …;
    callback(data);
}

This is very flexible, but maybe too complex. If you want something simpler, you can always just pass the selector and target, just as you thought:

[somebody doSomethingAndCall:@selector(dataReceiver:) on:self];

- (void) doSomethingAndCall: (SEL) selector on: (id) target
{
    NSArray *data = …;
    [target performSelector:selector withObject:data];
}

Or you can use a protocol:

@protocol DataConsumer
- (void) handleData: (NSArray*) data;
@end

// this class has to implement DataConsumer
[somebody doSomethingAndNotify:self];

- (void) doSomethingAndNotify: (id <DataConsumer>) consumer
{
    NSArray *data = …;
    [consumer handleData:data];
}

This solution is a bit heawyweight, but the advantage is that the compiler catches some errors for you. There’s also more coupling, but it’s far from being a problem.

Upvotes: 2

Jasarien
Jasarien

Reputation: 58478

You may wish to reconsider how you approach this problem.

Rather than trying to get your MasterUtilities instance to send the data to your other method, why not have your getData method return the data from the method and then have your ReportsViewController pass the data to dataReciever: ?

Upvotes: 0

Gonzalo Larralde
Gonzalo Larralde

Reputation: 3541

You have to use the Target-Action design pattern, which is widely used in Cocoa.

Good luck!

Upvotes: 1

Related Questions