On Mar 4, 2009, at 12:11 AM, Michael Ash wrote:

On Tue, Mar 3, 2009 at 4:30 PM, Quincey Morris
<quinceymor...@earthlink.net> wrote:
On Mar 3, 2009, at 12:50, Nick Zitzmann wrote:
It doesn't seem to be documented, but I think it will return nil only if
(1) there was not enough contiguous RAM in the program's VM space to
allocate the object, or (2) there was, but the user has run out of disk space for swap files. But if this happens, the program is pretty much
screwed anyway, because it's going to crash.

Yes, I'm aware of the "is pretty much screwed" scenario, but I think there are in fact some recoverable scenarios. One involves a sequence of very large (valid) allocations gobbling up VM space so that it becomes impossible to create a humbler NS... object of some kind. If the application doesn't crash right away, returning nil (or NO) back through the sequence could release all the memory and allow the application to continue with an error
message.

Another scenario is a memory-limited environment like the iPhone.

In either environment, once allocations start to fail for any reason,
you are doomed.

Recovery is possible, nay reasonable, if you control all of the code
in the process. But you don't, and you can bet that Cocoa is *not*
written with an eye toward gracefully recovering when malloc() begins
to return NULL.

You can try to recover from an allocation error, but what if the first
NULL allocation happens inside Cocoa code somewhere? If you're lucky
it'll end up trying to insert it into a collection or something
similar, trigger an assert, and throw an exception. If you're unlucky,
the NULL allocation will happen while trying to resize an
NSDictionary's hash table and you'll be set up for a crash.

Even if you could trap it and recover gracefully by dumping a large
allocation, multithreading means that you still have a window of
opportunity in between the failure and the allocation dumping where
other threads will see allocation failures too. And again, these can
happen deep in Cocoa code where you have no chance to survive.

Realistically, unless you're a pure libc program, the only way to deal
with out-of-memory situations is to detect it in advance and free up
memory *before* the allocations begin to fail, the way the iPhone
frameworks do it.

In an attempt to NOT derail my original topic, I've renamed this thread (I hope)...

Perhaps it's because I come from the old school ways, I find it nearly impossible for me to write code that doesn't check for NULL - regardless of the API's documentation or intent. The one true thing is that things can and do go wrong -- logically -- in computer programs. So, I am just in the habit of always checking for NULL. I'm just not yet that comfortable of stacking things up and doing the Cocoa/Java way. I also wrap things up inside of try...catch blocks as well, which will help protect in the case of legitimate memory failure. Of course, in this case, if something as small as an NSMenu fails due to memory issues, something's going to go terribly wrong. However, loading a large image, maybe not - and (graceful) recovery is much more possible.

Long ago in Classic MacOS programming days, we had some nice hooks into memory heap allocation - and you could plug in a function that would get called if a memory allocation failed, which would give you a chance to deallocate cached data or to gracefully recover without user data loss. I'm not as familiar with Cocoa (yet) as many on this list, but I'd be surprised if the Obj-C/Cocoa system didn't have something similar.

I also know that many mission-critical software development projects employ their own memory management schemes - and don't rely on the underlying Standard Lib stuff.

In any case, and perhaps based purely on habit, I find it difficult to even write:

        NSStatusItem statusItem = [[[NSStatusBar systemStatusBar]
                statusItemWithLength:NSVariableStatusItemLength] retain];

...in favor of:

        NSStatusBar *systemBar = [NSStatusBar systemStatusBar];
        if (systemBar != NULL)
        {
                NSStatusItem statusItem =
                        [systemBar statusItemWithLength:
                                NSVariableStatusItemLength];
                if (statusItem != NULL)
                {
                        [statusItem retain];
                        ...
                }
        }

There's something that's just "uncomfortable" about dereferencing pointers without first checking for validity. Is it just me?
M
M

--
Mark D. Gerl, Multimedia Design Group, <mailto:mg...@mmdesigngrp.com>

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to