According to the documentation of CLLocationManagerDelegate
The methods of your delegate object are called from the thread in which you started the corresponding location services. That thread must itself have an active run loop, like the one found in your application’s main thread.
I am not clear as to whether this means that to receive location manager updates on a background thread, we must instantiate the location manager on that background thread or simply call the startUpdatingLocation()
method on that thread.
In any event, this explains an issue when a CLLocationManagerDelegate
does not receive any events from a CLLocationManager
which was started on a background thread:
That thread must itself have an active run loop
If I understand run loop functioning correctly, all NSThreads
are instantiated with a run loop, but the run loop will only be running if you assign some work to the thread. Therefore, to have a CLLocationManager
send events correctly on a background thread, we need to set the thread's run loop to loop permanently so that it can process the CLLocationManager
's calls as they arrive.
A reasonable solution to making sure the run loop is running is suggested in this question but the author implies that this is a processor expensive way of doing it.
Also, according to the threading documentation,
Threading has a real cost to your program (and the system) in terms of memory use and performance
I appreciate that we are all using lots of threading anyway, by using Grand Central Dispatch, but Grand Central Dispatch probably mitigates a lot of this in its internal thread management.
So my first question is, is it worthwhile setting up a background thread with a continuously running run loop, in order to have location events dealt with on a background thread, or will this involve an unreasonable extra amount of processing when compared to leaving the manager on the main thread?
Secondly, if it is worthwhile, is there a good way to do this using Grand Central Dispatch. As I understand the documentation, Grand Central Dispatch manages its own threads and we have no means of knowing which thread a given block will be executed on. I presume we could simply execute the usual run loop code to make the run loop of whichever thread our CLLocationManager
instantiation is run on loop continuously, but might this not then affect other tasks independently assigned to Grand Central Dispatch?
NSThread
with a continuous run loop are likely to outweigh the performance implications of receiving events on the main thread before dispatching them using GCD? – Selfgovernment