Timing an operation and fire a delegate when it takes a long time to tell the user to wait
I've created an NSOperation to do some heavy work in background but I need to notify the user when it takes longer time than usual.
- (void)timerFireMethod {
if (_TheOperationStillWorking) {
// fire a delegate on the main thread to update the user interface...
}
}
- (void)doSomeHeavyWork {
_TheOperationSti开发者_C百科llWorking = YES;
NSTimer * timer = [NSTimer timerWithTimeInterval:5000 target:self selector:@selector(timerFireMethod:) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
// Some code that BLOCKS the current NSOperation that executes this function...
_TheOperationStillWorking = NO;
}
I've tried the NSTimer class but as the code blocks the current thread, because it reads synchronously some large data from the internet, the NSTimer won't fire. Is there any better way to accomplish that and if NSTimer is the best way how to use it?
Any help would be greatly appreciated, and thanks in advance.
You can schedule the timer from the main thread:
- (void)doSomeHeavyWork {
_TheOperationStillWorking = YES;
[self performSelectorOnMainThread:@selector(scheduleTimer) withObject:nil waitUntilDone:NO];
// Some code that BLOCKS the current NSOperation that executes this function...
_TheOperationStillWorking = NO;
}
- (void)scheduleTimer {
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5000 target:self selector:@selector(timerFireMethod:) userInfo:nil repeats:NO];
}
- (void)timerFireMethod {
OSMemoryBarrier(); // make sure private var is up to date
if (_TheOperationStillWorking) {
// updates here will happen on the main thread...
}
}
For info on why you need OSMemoryBarrier()
to protect your variable, see this page.
精彩评论