2014-02-22 39 views
0

以下代碼來自Big Nerd Ranch iOS編程手冊第3版。它是一個類方法,用於檢查單例類BNRItemStore是否已被實例化。如果有,它將返回單例實例,如果它沒有創建它。我不明白的部分是靜態變量。我知道靜態變量保持狀態,但是,不會再次調用該方法將* sharedStore重置爲nil?即一旦該方法被再次調用,這不是一個將刪除單例實例的創建的分配嗎?爲什麼不設置一個靜態變量來消除靜態變量的目的?

static BNRItemStore *sharedStore = nil; 

方法

+(BNRItemStore *)sharedStore 
{ 
    static BNRItemStore *sharedStore = nil; 
    if (!sharedStore) 
     sharedStore = [[ super allocWithZone:nil ] init ]; 
    return sharedStore; 
} 
+0

這是C的「靜態」實現的一個奇怪點:不管靜態變量在哪裏聲明,在聲明語句**中發生的任何初始化**都只執行一次。 –

回答

1

的代碼是好的,初始化劑只被稱爲第一次。

+0

我想你誤解了我的問題。我在問爲什麼初始化器不會被第二次調用。換句話說,如果我第二次調用sharedStore,是不是將靜態變量* sharedStore設置爲nil,這意味着沒有共享存儲,因此'if(!sharedStore)'中的代碼會運行? – BrainLikeADullPencil

+0

這更有幫助嗎? http://stackoverflow.com/questions/5567529/what-makes-a-static-variable-initialize-only-once這種行爲在Objective C中是一樣的。 – Douglas

+0

是的,現在我得到它謝謝 – BrainLikeADullPencil

0

靜態初始化程序由語言規範保證只執行一次(實際上這是在應用程序啓動時完成的,而不是作爲函數執行的一部分),所以靜態變量只會在第一次函數時爲零被執行。

2

不幸的是,C術語確實令人困惑。 static與單身沒有任何關係,靜止不動,或者其他任何事情。它與存儲發生的級別有關。

在方法/函數內部聲明的變量通常是一個自動變量,意思是當範圍結束時(即執行到達周圍大括號的末尾),它變得不存在。但是,聲明爲static的變量存儲在保存代碼的文件級別;一旦文件被加載,這個變量仍然存在,即使它是在方法/函數中聲明的。

現在我們來談談如何知道這個變量是否曾經被分配過一個值,因爲你只想分配一次。理論上,static變量在最初聲明時具有零值。因此,如果你只是說

static BNRItemStore *sharedStore; 

...代碼可能會奏效,因爲零是一個實例爲零,所以我們可以測試對零,只有在這種情況下,分配一個值。但是,確保雙重保證並沒有壞處。因此,我們通常在聲明變量時將變量初始化爲零,這樣我們就可以確定我們的第一次測試將會第一次運行。

即初始化,因爲你已經被告知,然後將生效只有一次,因爲在那之後,值保持等變量永遠需要重新初始化(決不是)。

+0

一個解釋是,「靜態」一詞描述了變量存儲在內存中的哪個位置。一個普通的自動變量被存儲在內存中的不同位置,這取決於它自動在調用棧中的位置,但是一個靜態變量總是存儲在同一個地方,所以當它在不同的上下文中被再次訪問時,它仍然包含相同的值。 – Douglas