2012-11-28 23 views
5

什麼是使用這個的好處是:爲什麼被分配了一個零,以單身的靜態變量

+ (CardPainter*) sharedPainter { 
    static CardPainter* sp = nil; 

    if (nil == sp) { 
     sp = [[CardPainter alloc] init]; 
    } 

    return sp; 
} 

,而不是這樣的:

+ (CardPainter*) sharedPainter { 
    static CardPainter* sp = [[CardPainter alloc] init]; 

    return sp; 
} 

靜態變量的初始化只進行一次,所以我看前者沒有優勢。

+3

http://stackoverflow.com/a/12304815/1861302 – melanye

+5

前者的優點是,它的作品,後者甚至不進行編譯。 – rmaddy

回答

-2

因爲如果你不問,你會initiatlite「* SP」你所撥打的「sharedPainter」,丟失任何數據的任何時間。

所以,如果你問,如果SP是零和的答案是假的意思是「SP」已經被初始化,並返回實例。如果答案是真的,那意味着sp沒有被初始化,只是在這種情況下你調用init函數。

+0

這與你是否檢查指針是否爲零沒有關係,爲什麼不直接調用初始化行上的'alloc init' –

+0

好吧,實際上靜態聲明不能在sharedPainter函數上,必須在實現之前。 – Vertig0

+0

@PatricioIgnacioFariaValdivi:嗯...什麼?當然你可以在函數裏面有靜態變量 – user102008

1

好,在編譯器的水平有幾個重疊的原因......想想的是,靜態變量存儲在編譯的應用程序,這是剛剛映射到內存,是一個專門的數據部分最簡單的。所以編譯器必須準確知道編譯時的內容。任何Objective-C方法調用的結果在編譯時根據定義和實踐是不可預知的 - 您從不知道在運行時不會發生什麼「有趣」的事情來改變該方法調用的行爲,所以您不需要肯定知道會返回什麼。

這與所有有點不同C++,出於各種原因(關鍵是C++具有構造函數,而Objective-C不具備)。但是,即使在C++中它在仍然皺着眉頭有以下幾個原因:

  1. 構造順序是不可預測的,但它很容易與常見的有構造彼此依賴,這意味着你的程序可以在運行時未定義行爲(包括數據損壞或崩潰)。
  2. 很多非平凡物體的初始化可能很昂貴。在啓動時一起做這件事可能會很有效,但它會讓您的應用程序啓動速度變慢,這種情況更糟糕。

後一點同樣適用於Objective-C的。您可以在啓動時避免做的越多,而是按時按需提供,用戶體驗通常就越好。

[注意,有一個noteable例外「沒有靜態對象實例」的規則,這是字符串,則@「foo」的形式。這些實際上是在您的應用程序的數據部分編碼爲真正的實例(一個特殊的NSString子類),它們只是在啓動時映射並且按原樣運行。但是,這是非常仔細的架構和運行編譯器在這方面緊密耦合,以確保一切順利。它並不一般適用。 ]

相關問題