WolfLink
WolfLink

Reputation: 3317

iOS: Detect low-memory crash outside of main run loop

In one of my apps, I am doing a lot of calculations involving arrays and graphing them. The calculations involve user input, and sometimes, if the user inputs crazy values, the app will keep performing the calculations until it takes up too much memory and is killed. When the user tries to open the app again, it will try the same calculations from the last saved data and will crash again. The user needs to delete and redownload the app in order to revert to the default values.

To fix this problem, I want to dump all the saved data when the app is killed due to low memory. I have tried implementing applicationDidReceiveMemoryWarning: in my appDelegate and didReceiveMemoryWarning: in the viewController where the calculations are going on. Neither of these functions is being called. After researching a bit, I figured out that it was because I am blocking the main run loop.

How can I best handle this situation?

Upvotes: 1

Views: 512

Answers (1)

lxt
lxt

Reputation: 31304

You should basically never be blocking the main run loop. You can block the user interface (with a modal loading screen or similar), but if you block the main run loop you're setting yourself up for all sorts of problems down the line.

There are lots of ways to shift your work onto a secondary thread - one of the easiest / highest level options is to use performSelectorInBackground:. If you need more finite control you can use NSOperation and NSOperationQueue, or go all the way down to GCD (hopefully you won't need to get this low level).

Another advantage of putting the work on a secondary/background thread is that you could let the user perhaps cancel the operations if it seems to be taking too long, maybe by having a "Cancel" button. When the user taps this you can cancel the operations taking place, and avoid these memory warnings happening in the first place.

But don't forget that any UI work needs to happen back on the main thread. So once you've done your processing, make sure you update the graph itself on the main thread (using performSelectorOnMainThread etc).

Upvotes: 1

Related Questions