views:

72

answers:

3

I am reading tutorial book now. When I see an example, I get some confused. The following codes show a way for lazy loading. Does this motivations array be released after instance deallocated ? or will it occupy this memory block until application terminates.

+ (NSArray *)motivations
{
    static NSArray *motivations = nil;
    if (!motivations)
    {
        motivations = [[NSArray alloc] initWithObjects:@"Greed",@"Revenge",@"Bloodlust",@"Nihilism",@"Insanity",nil];

    }
    return motivations;
}

Edit 1 Thank Georg for a bug.

+2  A: 

Because it is a static object, so the system will store the object pointer until the application is terminated. You can use this way to cache by let your pointer point to an object that is not release or autorelease

I recommend to use this approach when you really want to cache some data in memory (usually small or big images data) that requires a lot of CPU or IO processing time to generate. For small data like NSString, you can create new array and return every time you need.

Edit for the comment: There are 2 things about imageNamed:

1/ You cannot control what is cached and what is not cached by imageNamed:. You may not want to cache an image with big size and only used once, for example.

2/ imageNamed: cannot be used for getting image from Network or folders in the system. It will only load from your bundle

vodkhang
Note that `static` only affects the storage of the pointer `motivations`, the arrays life-time is completely independent from it.
Georg Fritzsche
As for image, under iPhone SDK, the imageNamed will cache the image in the system. Is it necessary to cache an image again in codes ?
Toro
there are 2 things: 1/ you cannot control imageNamed, what it will cache and what it will not. You definitely don't want to cache an image of 3 or 10 MB for example. 2/ You cannot load all image with imageNamed, for example, the image is in a specific path in the system or the image downloaded from the Internet
vodkhang
@Georg: that's right, I should be more specific
vodkhang
Thank you very much.
Toro
+3  A: 

The example you show has a bug - +arrayWithObjects: returns an autoreleased instance which will be destroyed later. The code was probably intended to be:

motivations = [[NSArray alloc] initWithObjects:@"Greed",@"Revenge",@"Bloodlust",@"Nihilism",@"Insanity",nil];

With that, the array will live until the application terminates.

Georg Fritzsche
ah yeah, I even don't notice this bug
vodkhang
^^" Thank you, I doesn't notice this bug too.
Toro
I filed this as a bug on the static analyzer (analyzer should catch autoreleased objects being assigned into static variables): http://llvm.org/bugs/show_bug.cgi?id=4955
Dave DeLong
+1  A: 

Since this is a class method (indicated by a + instead of a - at the declaration), there is no instance that will be released. (Technically there is an instance of an object of class isa I think (? comment if I'm wrong please, I don't know the inner workings very well) but don't worry about that)

So the class, which exists in memory the whole time the program is running, owns that array. Think of static as about as close as you can get to a class variable, rather than an instance variable. Since the class exists the whole time, the array exists the whole time.

Lazy loading keeps it from being created until the first time that class method is called though, so it isn't wasting memory until you need it.

Alex Gosselin