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.
ED开发者_如何学GoIT: 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.
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.
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
Actually on iOS 4 I prefer using NSNotifications and Observers (with Blocks) to perform updates on the mainthread.
- (id)addObserverForName:(NSString *)name object:(id)obj queue:(NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *))block
I wrote down my design here.
1) Declare your delegate's protocol to extend the NSObject protocol in the .h file
@protocol YourDelegateProtocol <NSObject>
2) Cast to NSObject in your call
[(NSObject*)delegate performSelectorOnMainThread:@selector(getDealersIDSuccess:) withObject:result waitUntilDone:YES];
I definitely recommend number (1).
精彩评论