First approach: using a delayed selector
Probably the simplest way to do this is to use NSObject's performSelector:withObject:afterDelay:
method. You can define some method parsingDidTimeout
as such:
- (void)parsingDidTimeout {
if(self.parsingDidComplete == NO) {
[self.parser abortParsing];
// Create your error and display it here
// Try the fetch and parse again...
}
}
This requires that you hang on to the parser as an instance variable (self.parser
), so that you can cancel it from the method you define. It also requires that your parser delegate keep track of whether or not the parser has finished (self.parsingDidComplete
, can be defaulted to NO
and set to YES
in the delegate's parserDidEndDocument:
method). This is to avoid aborting a successful parse. After this is done, all it takes is a simple
[self performSelector:@selector(parsingDidTimeout) withObject:nil afterDelay:30];
and thirty seconds later, your parsing-abort code will get called, and you can do whatever it is you need to do.
Second approach: using a timer
You could make this whole approach (arguably) simpler in the timeout method by using an NSTimer instead of the NSObject method call. That way, if the parser successfully finishes, you can simply invalidate the timer, allowing you to eliminate the if
clause in the parsingDidTimeout
method (and, as a result, also getting rid of the BOOL
ivar). The timer initialization would look like:
NSTimer *timer = [NSTimer timerWithTimeInterval:30.0
target:self
selector:@selector(parsingDidTimeout)
userInfo:nil
repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];