Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiler gives warning on performSelectorOnMainThread:@selector(delegateMethod)

I have an NSOperation that wraps some web service functionality. The NSOperation has a delegate that is to be messaged when the operation is over.

As the NSOperation lives on a different thread I have to make the call like this:

[delegate performSelectorOnMainThread:@selector(getDealersIDSuccess:) withObject:result waitUntilDone:YES];

It works just fine, but it gives me a warning:

warning: '-performSelectorOnMainThread:withObject:waitUntilDone:' not found in protocol(s)

I completely agree with the compiler on this one, it sees a delegate, it checks the protocol, it finds no declaration of a performSelector method.

My question is: can I remove the warning by making this call in a different manner?

My two guesses are that I could (1) write a method called

- (void) callDelegateMethodOnMainThred {
    [delegate getDealersIDSuccess:result]
}

and call that through performSelectorOnMainThread, but I find that solution to be cumbersome and an extra, hard to read, step on top of the delegation.

The second solution could be to cast the delegate to the type of my parent object inside the selector, but that is just plain crazy and goes against the delegate encapsulation pattern.

I would really appreciate a third solution from someone with a better understanding of the language:)

Thank you in advance.

EDIT: Added delegate declaration:

id <ISDealersIDDelegate> delegate;

I declare my delegate as id. The delegate it self extends UIViewController.

I could see that declaring it NSObject would work.

like image 271
RickiG Avatar asked Dec 21 '10 12:12

RickiG


2 Answers

performSelectorOnMainThread:withObject:waitUntilDone: method is declared in NSObject class. If your delegate object inherits from NSObject you can declare it as

NSObject<MyDelegateProtocol> *delegate;

So compiler will know that delegate responds to NSObject's methods and won't issue a warning.

like image 97
Vladimir Avatar answered Oct 19 '22 09:10

Vladimir


It might be even a better solution not call performSelectorOnMainThread: on a delegate or other protocol implementation. Make it the responsibility of the delegate/receiver to determine if it needs to do things on the main thread.

[delegate performSelector:@selector(delegateAction:)
               withObject:actionData];

Delegate implementation

- (void)delegateAction:(NSData*)actionData
{
    [self performSelectorOnMainThread:@selector(updateUIForAction:)
                           withObject:actionData
                        waitUntilDone:NO];
}

- (void)updateUIForAction:(NSData*)actionData
{
    // Update your UI objects here
}

It might look like more code, but the responsibility is in the right place now

like image 3
Maarten Avatar answered Oct 19 '22 09:10

Maarten