【问题标题】:Is this valid code to create a NIB-instantiated singleton?这是创建 NIB 实例化单例的有效代码吗?
【发布时间】:2011-03-27 23:55:28
【问题描述】:

假设我在 NIB 中实例化了 MyGreatClass 类的对象(像往常一样,只需将“对象”拖到 NIB 并将其类设置为 MyGreatClass)。

我想在我的代码库中的任何地方访问该实例,而不引入耦合,即不疯狂地传递对象,也没有在 [NSApp 委托] 中的出口。 (后者会使 AppDelegate 随着时间的推移变得非常庞大。)

我问:以下是否被认为是完成此任务的好代码?

//imports

static MyGreatClass *theInstance = nil;

@implementation MyGreatClass

+ (MyGreatClass *)sharedInstance
{
  NSAssert(theInstance != nil, @"instance should have been loaded from NIB");
  return theInstance;
}

- (id)init //waking up from NIB will call this
{
  if (!theInstance)
    theInstance = self;
  return theInstance;
}

// ...

如果按预期工作,我会在应用加载后能够通过 sharedInstance 访问我的实例。

你怎么看?

更新:嗯,再想想,上面的 init 方法可能有点矫枉过正。这更容易考虑:

- (id)init
{
  NSAssert(!theInstance, @"instance shouldn't exist yet because only "
                         @"the NIB-awaking process should call this method");
  theInstance = self;
  return theInstance;
}

再说一遍,你怎么看?

【问题讨论】:

  • 它可能会起作用,但为什么要把它放在笔尖里呢?为什么不让类自己处理单例行为呢?示例:getsetgames.com/2009/08/30/the-objective-c-singleton
  • 感谢您的回复。在这种情况下,我在 NIB 中使用了它,因为该类还有一些与菜单项连接的操作方法。事实证明,我需要在另一个地方以编程方式设置该目标/动作。这有意义吗?
  • 不,因为如果您以编程方式设置目标/操作,那么与笔尖的连接是什么?只有控制器应该有 IB 出口/动作。但如果它是一个单例控制器,我想这是有道理的,不知何故。

标签: objective-c cocoa


【解决方案1】:

创建单例的正确方法是覆盖allocWithZone: 以确保无法创建另一个对象。重写 init 允许创建新对象,但不初始化。它被丢弃是因为 init 方法简单地忽略它并返回已经创建的对象。这是我的做法:

+ (MyGreatClass *)sharedInstance {
    NSAssert(theInstance != nil, @"instance should have been created from NIB");
    return theInstance;
}

+ (MyGreatClass *)allocWithZone:(NSZone *)zone {
    if(theInstance) return theInstance;
    return [[self alloc] init];
}

- (id)init {
    if(theInstance) return theInstance;
    if(self = [super init]) {
        theInstance = self;
        // other initialization
    }
    return self;
}

- (void)release {}
- (void)dealloc {
    return;
    [super dealloc]; // Prevent compiler from issuing warning for not calling super
}

我覆盖了releasedealloc 以确保不会释放单例。如果你不这样做,你应该在sharedInstance 方法中保留并自动释放它。如果要支持多线程,还应该同步对theInstance变量的访问。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多