在Interface Builder中使用Singleton?

Dan*_*ark 5 objective-c

我有一个像这样的Singleton设置:

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;
}
Run Code Online (Sandbox Code Playgroud)

但现在我意识到我想从Interface Builder中实例化它.我正在考虑切入init这样的方法

    if (instance) 
         return instance;
Run Code Online (Sandbox Code Playgroud)

这是一个坏主意吗?我更喜欢IB来获取已经在+initialize方法中创建的实例.

Nic*_*ore 6

这可以做到.Buck和Yachtman 在Cocoa Design Patterns中有一节介绍它.

在你的情况下,你可以做一些事情:

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;
}
Run Code Online (Sandbox Code Playgroud)

然后,nib加载代码将通过调用正确地获取单例[[Universe alloc] init],并且您仍然可以instance像以前一样在代码中使用它.

这本书有更多的细节,并建议实现newallocWithZone(简单地说return [self alloc];),加上错误报告存根,copyWithZone以及mutableCopyWithZone好的措施.

  • `+ alloc`应该返回`[[self instance] retain]`,因为`alloc`返回一个拥有的对象. (2认同)
  • @invariant我刚刚在勘误表页面上提交了它:http://www.cocoadesignpatterns.com/errata/ (2认同)