2011-03-27 22 views
0

假设我在我的NIB中实例化MyGreatClass类的对象(通常只需将一个“Object”拖动到NIB并将其类设置为MyGreatClass)。这是创建一个NIB实例化的单例的有效代码吗?

我想要在我的代码库中的任何位置访问该实例,而不引入耦合,即不会像疯了一样传递对象,也不会在[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; 
} 

再次,你怎么看?

+0

它会正常工作,但为什么把它放在笔尖内?为什么不让班级自行处理单身人士的行为呢?例如:http://getsetgames.com/2009/08/30/the-objective-c-singleton/ – vakio 2011-03-28 00:08:00

+0

感谢您的回复。在这种情况下,我在NIB中使用过,因为这个类也有一些操作方法与菜单项有联系。然后,事实证明,我需要在另一个地方以编程方式设置该目标/行动。那有意义吗? – Enchilada 2011-03-28 01:52:25

+0

不,因为如果以编程方式设置目标/动作,那么与笔尖的连接是什么?只有管​​制员应该有IB出口/行动。但是,我认为这是一个单身控制器,不管怎样,这都是有道理的。 – vakio 2011-03-28 07:36:09

回答

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变量。

相关问题