Short question: Can you restart background processes with XCode somehow?
Long question:
I'm coding an app with XCode that includes a clustering algorithm for markers on its MKMapView. The clusters have to update each time the map is moved, and with 3000+ locations this takes about 2 seconds. The clustering basically consists of a for-loop over all locations, and only clusters and draws location visible for my current region, counting both position and zoom. Since it takes some time, I have made the clustering algorithm a background process launched it with.
[self performSelectorInBackground:@selector(clusterizeAndStopSpinnerWhenDone) withObject:nil];
As you can now interact with the map while it's performing the background clustering, moving the map again while the application will cause two threads to enter the same for loop:
"Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x17cc5060> was mutated while being enumerated.'"
This was fixed by simlpy having a boolean telling the app if the clustering was already running or not.
This new setup works, but one thing is bugging me. It appears from the following set of actions:
So you zoom out to get a new region on the map, and then you zoom out again. The old clustering continues and the new region is not taken into account. This results in a clustering that does not match my current map region.
I would like it to instead restart the clustering each time the map is moved and do it for the new region, for this I would have to interrupt the old clustering and start a new one. Is this possible?
Posting Vladimirs answer as the correct answer:
It may be difficult once function has already started. Take a look at NSOperation - it will allow to structure your code in a more clear way and it supports cancelling, also note that you'll have to adjust your clustering function to be able to return in the middle if it was cancelled
My reply:
NSOperation was exactly what I was looking for. Inside the for-loop I can have a check to see if the operation has been canceled each loop, and I can start a new operation easily. Thanks a lot!