I have an asynchronous server request in my iOS app:
[self performSelectorInBackground:@selector(doSomething) withObject:nil];
How can I detect the end of this operation?
I have an asynchronous server request in my iOS app:
[self performSelectorInBackground:@selector(doSomething) withObject:nil];
How can I detect the end of this operation?
Put a call at the end of the doSomething method?!
- (void)doSomething {
// Thread starts here
// Do something
// Thread ends here
[self performSelectorOnMainThread:@selector(doSomethingDone) withObject:nil waitUntilDone:NO];
}
If you just want to know when it's finished (and don't want to pass much data back - at which point I would recommend a delegate) you could simply post a notification to the notification center.
[[NSNotificationCenter defaultCenter] postNotificationName:kYourFinishedNotificationName object:nil];
within your view controllers viewDidLoad method add:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(yourNotificationListenerMethod:)
name:kYourFinishedNotificationName
object:nil];
and within dealloc, add:
[[NSNotificationCenter defaultCenter] removeObserver:self];
You may want to have your doSomething selector post back when it has completed itself. What happens on performSelectorInBackground is internal to the API and if you want more control you may want to use performSelector:onThread:withObject:waitUntilDone:
and periodically check the isFinished
on the thread passed. I am sure you are more concerned about doSomething finishing than the actual thread though so just post back from there.
I have a general background handler I created that solves this problem. Only the first method is public so it can be used throughout. Note that all parameters are required.
+(void) Run: (SEL)sel inBackground: (id)target withState: (id)state withCompletion: (void(^)(id state))completionHandler // public
{
[(id)self performSelectorInBackground: @selector(RunSelector:) withObject: @[target, NSStringFromSelector(sel), state, completionHandler]];
}
+(void) RunSelector: (NSArray*)args
{
id target = [args objectAtIndex: 0];
SEL sel = NSSelectorFromString([args objectAtIndex: 1]);
id state = [args objectAtIndex: 2];
void (^completionHandler)(id state) = [args objectAtIndex: 3];
[target performSelector: sel withObject: state];
[(id)self performSelectorOnMainThread: @selector(RunCompletion:) withObject: @[completionHandler, state] waitUntilDone: true];
}
+(void) RunCompletion: (NSArray*)args
{
void (^completionHandler)(id state) = [args objectAtIndex: 0];
id state = [args objectAtIndex: 1];
completionHandler(state);
}
Here's an example of how it's called:
NSMutableDictionary* dic = [[NSMutableDictionary alloc] init];
__block BOOL done = false;
[Utility Run: @selector(RunSomething:) inBackground: self withState: dic withCompletion:^(id state) {
done = true;
}];