2011-03-27 24 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變量。

相關問題