开发者

Compiler gives warning on performSelectorOnMainThread:@selector(delegateMethod)

开发者 https://www.devze.com 2023-01-31 09:48 出处:网络
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.

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).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号