tags:

views:

200

answers:

2

As far as I know there are 2 levels of memory warnings. applicationDidReceiveMemoryWarning doesn't come with the warning level. Is there a way to get this information?

+1  A: 

It's not that there are two levels of warning--not in terms of, like, "you have a little memory left" and then "you have less memory left". It's that the same "low memory" warning gets fired two places. Once on the UIViewController subclass currently in view (and, if that UIVC doesn't implement didReceiveMemoryWarning, then it'll bubble up to the top of the view controller stack) and again on the Application Delegate in applicationDidReceiveMemoryWarning. One's not a "worse" warning than the other, they're just two different hooks for implementing a response to the same warning from the OS.

It's one of the quirks of the platform that you can't really know how much memory you'll have available at any time. Background apps (mail, phone, etc) suck as much RAM as they need, and you're left to get the rest, and the only way you can know you've gotten too big is when the OS says so.

It's important to respond appropriately, by ditching resources you don't need right now. Start with the low-hanging fruit--anything big you're keeping around for later. Images, for instance, that you can ditch and then pull from a server or from disk later when you need them again.

Dan Ray
I agree completely but I'm not sure we are talking about the same thing. At first I didn't implement any of the mentioned memory warning methods. What ended up happening is the following. After monkeying around in the app I got the following message in the debug console:"2010-08-06 11:12:42.880 blaApp[9591:207] Received memory warning. Level=1"I kept on doing what I did and a couple of seconds later I got"2010-08-06 11:12:55.171 blaApp[9591:207] Received memory warning. Level=2"And a few seconds later my app was gone. What I want to know is this level attribute.
A: 

I'm adding this as a separate answer than my other one, because it IS a separate answer. The answer I gave earlier is the practical one, the one you SHOULD use. It boils down to "deal with the one level of memory warning you're notified with and don't concern yourself with the details".

If, however, you really really want to know more about it, check out this undocumented API: http://www.opensource.apple.com/source/Libc/Libc-594.1.4/include/libkern/OSMemoryNotification.h

That's the header for kernel code that generates memory warnings, and it declares the following typedef:

typedef enum {
    OSMemoryNotificationLevelAny      = -1,
    OSMemoryNotificationLevelNormal   =  0,
    OSMemoryNotificationLevelWarning  =  1,
    OSMemoryNotificationLevelUrgent   =  2,
    OSMemoryNotificationLevelCritical =  3
} OSMemoryNotificationLevel;

We obviously don't have the implementation of the key method (OSMemoryNotificationCurrentLevel()) that does the math to say which warning to return, but that's the list of possible return values.

You could use the Mach.h library to test the actual memory levels on the device (let me know if you want some code that does that), and then use OSMemoryNotificationCurrentLevel() to get the current level of memory warning, and really map out the notification level to the physical state of the machine. Such an app would be completely unwelcome on the app store, and it wouldn't really help you any in real life development, where your job is to respond to the single level of low memory warning you receive.

Dan Ray
I got it. And thanks a lot for that information, that was quite useful. My train of thoughts was that if I only get kicked after warning level 2, maybe I can exploit that and do the real painful, retarding stuff only upon warning level 2.
I think warning level two means "you're going away now". In practice, you get one shot. You might get that one shot multiple times over your app's lifetime, but there's no "advisory" level of memory warning. You should treat your first warning as serious.
Dan Ray