Possible Duplicate:
UIScrollView pauses NSTimer until scrolling finishes
I am having a bit of trouble figuring out why the NSTimer stops as soon as I scroll in the UIWebView. Please take a look at the following code (I know this isn't a homework site, but I honestly am stuck):
- (void)viewDidLoad {
[super viewDidLoad];
NSString *address = @"http://en.m.wikipedia.org/wiki/";
NSURL *url = [NSURL URLWithString:address];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[wiki loadRequest:request];
time = 0;
countValue = 0;
timer = [NSTimer scheduledTimerWithTimeInterval: 0.1 target: self selector: @selector(updateTimer) userInfo: nil repeats: YES];
timeRand = 0;
countValueRand = 1;
randomTimer = [NSTimer scheduledTimerWithTimeInterval: 0.1 target: self selector: @selector(updateRandomTimer) userInfo: nil repeats: YES];
[self generateWordsArray];
}
Well user interaction blocks the main thread so the timer is delayed as it adds itself to the current thread's run loop.
If you want the timer to be called irrespective of user interaction, you should consider spawning a new thread and attaching the timer to that thread.
You can also look at a
GCD based timer
by Mike Ash which will run in the background. The only thing you should remember is that the UI updates must be done on the main thread.You have to add the timer to another RunLoopMode. Per default a timer is added to the NSDefaultRunLoopMode. That means that the timer is only executing when the app’s run loop is in NSDefaultRunLoopMode.
Now, when a user touches the screen (e.g. to scroll a UIScrollView) the run loop’s mode will be switched to NSEventTrackingRunLoopMode. And now, that the run loop is not in NSDefaultRunMode anymore, the timer will not execute. The ugly effect of that is, that timer is blocked whenever the user touches the screen. And that can be a looong time when the user is scrolling, because the timer is blocked until the scrolling completely stops. And when the user continues to scroll, the timer is blocked again.
Fortunately the solution to this problem is quite simple: You can add your timer to another NSRunLoopMode. When add the timer to NSRunLoopCommonModes it will execute in all run loop modes (that have been declared as a member of the set of “common” modes, to be precise). That means that the timer is not only working in NSDefaultRunLoopMode but also in NSEventTrackingRunLoopMode (when the user touches the screen).
So after you initialize your timer, add it to NSRunLoopCommonModes: