2012-09-06 56 views
13

我有這樣的代碼:「初始化元素不是編譯時常量」爲什麼?

- (NSString *) calculate: (uint) position { 
    static NSArray * localArray = [NSArray arrayWithArray: self.container.objects ]; 
    // some un related code 
    return obj; 
} 

編譯器會抱怨說:「初始值元素不是一個編譯時間常數」。當我將「static」添加到localArray時發生了這種情況。但爲什麼?

+0

http://stackoverflow.com/q/6143107/94687是同樣的問題。在你的問題中唯一特別的是將static關鍵字明確地添加到函數體內的變量中(但是這必須等同於在全局範圍內具有變量,就像在該問題中那樣)。 –

回答

28

因爲[NSArray arrayWithArray: self.container.objects ]不是編譯時常量,所以它是必須在運行時進行評估的表達式。在C和Objective-C中,函數內部的變量必須使用編譯時間常量進行初始化,而C++和Objective-C++更寬鬆並允許非編譯時常量。

要麼編譯代碼的Objective-C++,或者重構弄成這個樣子:

static NSArray *localArray = nil; 
if (localArray == nil) 
    localArray = [NSArray arrayWithArray: self.container.objects ]; 

這是相當類似,編譯器會在引擎蓋下生成一個static變量和初始化代碼非編譯時常量(實際上,它將使用第二個全局標誌,指示該值是否已初始化,而不是像這裏使用哨兵值nil;在這種情況下,我們假設localArray永遠不會是nil)。如果你願意,你可以檢查你的編譯器的反彙編。

+2

我建議使用'dispatch_once()'初始化'localArray'。這是線程安全和非常有效的。 – bbum

5

你只是不能初始化一個靜態變量,它具有一個在運行時將被知道/修改的非靜態值。

你或許應該做這樣的事情:

static NSArray *localArray = nil; 
localArray = ...; 

第一個指令將再次在您的應用程序生命週期執行。 每次調用calculate:方法時都會執行第二條指令。

儘管如此,請注意使用靜態變量會導致錯誤行爲,如果做得不好,所以如果您對這些行爲感到不安,您應該不要使用它們。

+2

+1「第一條指令將在您的應用生命週期中執行一次。」 – Philip007

相關問題