How to detect a level=2 memory warning in iOS?
Apple defines lev=1 and lev=2 memory warnings as very different (one is "hmm. not much memory around. Be careful", the other is "I am about to kill a process, you have 5 ... 4 ... 3 ...")
...but how do you find out programmatically which one you've received?
I have an iPad app which processes images with specialist tools, and lev=1 memory warnings are inevitable - even processing an image in small pieces, it still uses up a lot of memory just to display all the GUI etc.
I get lev=1 ALL THE TIME and there's literally nothing I can do about it.
lev=2 memory warnings are a very different matter. If I get a lev=2 that usually means that there's some background app taking up a lot of memory, or that something the user has done has bloated memory - and I need to take emergency action to prevent me getting killed. There are things that I can do - but ALL of them are bad for the user (e.g. remove all GUI, wait a couple of seconds, then reload it).
So ... I need two different code paths inside "didRecieveMemoryWarning": one for lev=1 warnings, and one for lev=2 warnings.
EDIT: some info on warning levels: iPhone OS Memory Warnings. What Do The Different Levels Mean?
NB: Apple frequently "doesn't document" things. If we as developers only stuck to the documented information, and the bug-free parts of the API,开发者_Python百科 then many (most?) of the boundary-pushing apps wouldn't exist until several iOS releases later. Instead, we work around the bugs, and we work out what's actually happening where Apple fails to document it.
EDIT2: ...looking into the linked header file, looks like that's got the underlying private function Apple uses to find out which level is current: "OSMemoryNotificationLevel OSMemoryNotificationCurrentLevel(void)" - but I guess there's no way we could get this past Apple Submission :( ?
I don't think the warning level is made available to applications but -- and I know this isn't what you want to hear -- that doesn't really matter. Just because the OS has two different levels of memory warning does not mean that you should do different things at each level and hope that other applications do the Right Thing.
The documentation says:
It is strongly recommended that you implement this method. If your application does not release enough memory during low-memory conditions, the system may terminate it outright.
There is no talk of "be careful" or "about to kill." That may be what currently happens, but is it the same in iOS5? Or in later versions? It's pretty dangerous to make those kinds of assumptions.
I think you need to consider optimising your memory usage. There's almost always a way to optimise images, release cached/intermediate data, more efficiently use autorelease pools, smaller/more efficent data structures. You don't say what techniques you're using currently so it's difficult to be specific.
An alternative approach that I have NOT TRIED but might work: Capture the output of Apple's system logger (ASL), look for the lev2 warning string.
Assuming Apple is actually using the ASL (which they might not be!) you could try following the instructions here: http://www.cocoanetics.com/2011/03/accessing-the-ios-system-log/ - which show how to access the ASL using Apple public API's.
精彩评论