views:

43

answers:

2

I am allocating memory in the class method initialize:

UIColor * customBlue;
UIColor * customRed;

@implementation UIColorConstants

+ (void)initialize{
 if ( self == [UIColorConstants class] ) { 
  customBlue = [[UIColor alloc]initWithRed:0 green:0.137 blue:0.584 alpha:1];
  customRed = [[UIColor alloc]initWithRed:.91 green:0.067 blue:0.176 alpha:1];
 }
}

+ (UIColor *)getCustomRed{
 return customRed;
}

+ (UIColor *)getCustomBlue{
 return customBlue;
}

@end

Where is the best / correct place to release the allocated memory since there is no counterpart to initialize called automatically?

+3  A: 

In the example that you give I would not bother with cleaning up. The amount of memory is very small and the only proper place where to clean up is when the app exits, at which point you really do not care about those objects anymore anyway.

One thing you might consider is to not keep those colors around and simply do:

+ (UIColor*) customRedColor {
    return [[[UIColor alloc]initWithRed:0 green:0.137 blue:0.584 alpha:1] autorelease];
}

Then you have useful little helper methods that do not require those objects to stick around. It will simply be the caller's responsibility to make sure the color is retained or not.

This is probably also better and simpler behaviour in a iOS 4.0 multitasking environment.

St3fan
Thank you for your reply. This is a good suggestion. I had also considered this to get around the allocation issue but considered performance of allocating on each request vs returning an already created instance. Since this is a low use (for now) allocating on each call should not have an impact. One draw back of returning the same instance as I originally had is the caller could modify the instance - your suggested approach would alleviate this.
luther_stanton
+2  A: 

There isn't one, so you don't release that memory; the OS reclaims it when your process exits. Once loaded and initialized, the class persists throughout the execution of the process (barring someone calling -[NSBundle unload]). Class data is expected to remain live for the same duration.

If you have a lot of class data, you could try lazily initializing it, e.g.:

+ (UIColor *)getCustomBlue {
    static UIColor *customBlue = nil;
    if (!customBlue) customBlue = [[UIColor alloc] initWithRed:0.0 green:0.137 blue:0.584 alpha:1.0];
    return customBlue;
}

customBlue is then not created until it is requested. If no-one uses it, then it never gets created, and never uses any heap memory.

ETA: St3fan is right that you can also just create a new autoreleased color on-demand. If creation is inexpensive, this is likely the best thing to do.

If you had a resource that would not be reclaimed by the OS for some reason, you could register an at-exit handler using atexit() to perform the cleanup:

static void
CleanupColors(void) {
    [customBlue release], customBlue = nil;
    [customRed release], customRed = nil;
}

+ (void)initialize {
    if (...) {
        ...
        atexit(CleanupColors);
    }
}
Jeremy W. Sherman
+1 i hadn't heard of `atexit` before. Neat!
Dave DeLong
If allocating and returning the same instance, lazy loading definitely seems a better approach - thank you for the answer / suggestion.
luther_stanton