Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Singleton In Interface Builder?

Tags:

objective-c

I have a Singleton set up like this:

static Universe *instance;

+ (Universe *)instance { return instance; }

+ (void)initialize
{
    static BOOL initialized = NO;
    if(!initialized)
    {
        initialized = YES;
        instance = [[Universe alloc] init];
    }
}

- (id) init
{
    self = [super init];
    if (self != nil) {
        self.showHistory = YES;
    }
    return self;
}

but now I realize that I'd like to instantiate it from Interface Builder. I was thinking of just cutting into the init method like so

    if (instance) 
         return instance;

is this a bad idea? I'd prefer IB to pick up the instance already created in the +initialize method.

like image 424
Dan Rosenstark Avatar asked Jan 05 '11 21:01

Dan Rosenstark


2 Answers

This can be done. There is a section about it in Cocoa Design Patterns by Buck and Yachtman.

In your case you could do something along the lines of:

static Universe *instance;

+ (Universe *)instance { return instance; }

+ (id)hiddenAlloc
{
  return [super alloc];
}

+ (id)alloc
{
  return [[self instance] retain];
}

+ (void)initialize
{
    static BOOL initialized = NO;
    if(!initialized)
    {
        initialized = YES;
        instance = [[Universe hiddenAlloc] init];
    }
}

- (id)init
{
  if(instance==nil) // allow only to be called once
  {
    // your normal initialization here
  }
  return self;
}

The nib loading code will then correctly pick up the singleton via its call to [[Universe alloc] init], and you can still use instance in your code as before.

The book has more detail and recommends implementing new and allocWithZone (both simply as return [self alloc];), plus error-reporting stubs to catch copyWithZone and mutableCopyWithZone attempts for good measure.

like image 160
Nick Moore Avatar answered Oct 17 '22 06:10

Nick Moore


That's going to leak. You can get away with it if you change it to:

if(instance) {
    [self release];
    return instance;
}

but it still smells a bit to me. I'm curious what use you have for singletons in IB; I suspect I would avoid this construct in my code.

like image 29
Seamus Campbell Avatar answered Oct 17 '22 07:10

Seamus Campbell