Reputation: 371
To begin, I realise I may be causing this problem by addressing a previous problem incorrectly...
In a ViewController
main thread I am starting a background thread to get updated data from a server using:
[self performSelectorInBackground:@selector(sampleTask:) withObject:@"CMD" ];
This process can take 15-30 seconds so in the main thread I display a local cache of the data from a SQLite database (populated from a previous request to the server the last time the view was opened) and reload the table once the sync with the server is finished.
If the user navigates back out of this view before the sync with the server is finished, the background thread keeps running until it is done. This itself isn't a problem, until the user changes their mind and goes back into this view again. If the timing is right, there's two background threads trying to sync data with the server. If the user does this a few times, the thread count can build up. Eventually the app will collapse, if not cause other problems on the device.
viewDidDisappear
?Or should I be writing a lock to a shared resource (e.g. NSUserDefaults
) to prevent a new background thread from being started?
Or -- like I mentioned in the first line -- do I have a bad approach to the issue of updating the local cache that is just causing further problems like this one?
Upvotes: 0
Views: 431
Reputation: 131471
performSelector:withObject:afterDelay:
does not create a separate thread.
To quote part of the docs on that method:
Invokes a method of the receiver on the current thread using the default mode after a delay
It uses a timer to trigger your selector after a delay. As such it is subject to the same accuracy limitations as NSTimer. (The method performSelectorInBackground:withObject:
does submit your selector on a background thread.)
But back to your question.
You can use the method
cancelPreviousPerformRequestsWithTarget:selector:object:
To cancel a pending call to performSelector:withObject:afterDelay:
Upvotes: 1
Reputation: 10096
I think you can use simple bool valued semaphore which shows that some sync task is performing. So before performing the next similar task you should check that semaphore. If you recreate your viewcontroller each time you need static class variable common for all instances of your view controller.
Upvotes: 1