2010-05-06 24 views
30

我試圖創建一個字符串文字分組的NSArray,但是我得到編譯錯誤「初始化元素不是常量」。如何用字符串文字創建NSArray?

NSArray *currencies = [NSArray arrayWithObjects:@"Dollar", @"Euro", @"Pound", nil]; 

有人能指出我做錯了什麼,並可能解釋錯誤信息嗎?

+0

你的代碼應該工作,你確定這個錯誤不是在其他地方嗎? – pheelicks 2010-05-06 16:53:45

+0

你應該說你把這條線放在哪裏,因爲它聽起來像你沒有把它放在方法中。 – malhal 2013-11-12 06:02:19

回答

18

這不是NSArray創建本身的問題(如果您改爲編寫[NSArray array],您會得到相同的錯誤),但是會寫入它的位置。我猜這是一個全局或文件靜態NSArray。在C中,那種類型的變量必須有一個常量初始化程序 - 這意味着不是函數調用(或者擴展方法調用)。解決的辦法是將數組的實際創建和賦值放入一個將在需要該數組之前調用的方法,如initialize

+1

我已經在頭文件中聲明瞭這一點,但並不知道我無法在方法之外初始化它。 – Kyle 2010-05-07 02:00:28

+0

將它安全地放在'+ load'裏面嗎? – user102008 2013-04-21 04:32:09

0

該代碼沒有問題。你確定錯誤是在該行生成的嗎?

2

我在Objective-C是一個新手,但我認爲正確的代碼是:

的NSArray *貨幣= [[NSArray的頁頭] initWithObjects:@ 「美元」,@ 「歐元」 @「磅」,無];

我不確定壽。

+2

這也是有效的,但是OP的代碼沒有問題。你的方法只保留了陣列,而他不 – pheelicks 2010-05-06 16:57:09

+0

然而,如果存儲在一個靜態變量的對象是** **不保留,這是一種潛在的不速之客錯誤,所以分配/初始化是做正確的事。 – jlehr 2010-05-06 20:34:12

7

聽起來像查克發現了這個問題。在編寫解決方案時,您想知道的一件事是,您需要避免將自動釋放的NSArray實例存儲在靜態變量中。此外,針對這些情況常見的模式是寫一個創建並返回保存在靜態變量的值,像這樣一類方法:

+ (NSArray *)currencies 
{ 
    static NSArray *_currencies; 

    // This will only be true the first time the method is called... 
    // 
    if (_currencies == nil) 
    { 
     _currencies = [[NSArray alloc] initWithObjects:@"Dollar", @"Euro", @"Pound", nil]; 
    } 

    return _currencies; 
} 
+0

嗨,爲什麼不建議將自動釋放對象存儲在靜態變量中?這是否是爲了提高效率,使他們不被要求在每個循環中保留數量? – 2011-04-22 21:13:23

+1

自動釋放池中的對象不會被要求保留計數;他們在釋放autorelease池時發送'release'消息。如果一個自動釋放的對象存儲在一個靜態變量中,一旦發生這種情況,該變量將包含一個無效的地址,並且試圖引用它會導致程序崩潰,甚至導致它錯誤地訪問某個在該處分配的新對象在此期間的地址。 – jlehr 2011-04-24 14:45:21

+0

是的這是真的,文檔還聲明,如果你保留一個autorelease對象,當池被耗盡時,你的對象將不會被釋放。如果您使用appkit,則會在每個事件循環中創建autorelease池,並在其末尾排空。所以我認爲它確實叫保留計數。 – 2011-04-28 03:15:14

3

雖然這是舊的,請注意,蘋果犯了一個新的補丁llvm項目增加了對NSArray,NSDictionaryNSNumber的新Objective-C文字語法的支持。

herehere

67

試試這個神奇:

NSArray *currencies = @[@"Dollar", @"Euro", @"Pound"]; 

而且是它必須是一個方法內。

+0

值得注意的是,如果它位於方法內部,它將被動態分配數組。我期望它是靜態常量數組。 – Andy 2013-08-08 09:24:38