2009-12-29 34 views
12

我已經閱讀了幾篇文章,並且在Apple的代碼指南中指出,在Objective-C中,字符串常量應該被定義爲extern NSString *const MY_CONSTANT;,並且應避免使用#define指令。這是爲什麼?我知道#define在預編譯時運行,但所有字符串將共享相同的內存地址。我讀到的唯一好處是,如果必須更新或更改常量,則不必重新編譯整個項目。所以我應該避免使用#define的原因?Objective-C#define指令被妖魔化爲字符串常量

感謝

UPDATE:在這種情況下是很好用的#define或有更好的方法嗎?

/* Constants Definition */ 
#define SERVER_URL @"http://subdomain.domain.edu.ar/Folder/" 
NSString *const ServerURL = SERVER_URL; 
NSString *const LoginURL = [email protected]"welcome.asp"; 
NSString *const CommandURL = [email protected]"com.asp"; 

回答

-2

據我所知,#define只允許你定義C風格的字符串常量。要創建一個常量NSString對象,必須在頭文件中聲明它,然後在其中一個.m文件中給它賦值。

頭文件

extern NSString *MyConstantString;

主文件:

NSString *MyConstantString = @"String value";

+0

爲什麼'#define HELLO @「World」'在Objective-C中不起作用? – Dirk 2009-12-29 23:17:53

+0

'#define MyConstantString @「String Value」'不起作用? – Chuck 2009-12-29 23:17:56

+0

#define只是一個文本替換,所以我不明白爲什麼#define MSG @「你好」不會工作 – GuidoMB 2009-12-29 23:24:34

10

它不一定保證只會有一個給定的字符串在整個應用程序的字面一個NXConstantString對象。看起來很可能不同的編譯單元對於同一個常量字符串可能有不同的對象。例如,如果有人編寫插件,則會爲插件中出現的NSString文字生成一個常量字符串,並且會爲主機應用程序中出現的一個字符串生成一個常量字符串,並且這些字符串不會是指針相等的。

17

使用常數而不是定義的一個實際原因是,您可以直接比較(使用==)而不是使用isEqual:。考慮:

NSString * const kSomeStringConstant = @"LongStringConstantIsLong"; 
... 
[someArray addObject:kSomeStringConstant]; 
if ([someArray lastObject] == kSomeStringConstant) 
{ 
    ... 
} 

這將工作,因爲==比較將比較相同常量指向單個NSString對象。使用#define,但是:

#define STRING_CONSTANT @"MacrosCanBeEvil"; 
... 
[SomeArray addObject:STRING_CONSTANT]; // a new const `NSString` is created 
if ([someArray lastObject] == STRING_CONSTANT) // and another one, here. 
{ 
    ... 
} 

工作了,因爲這兩個字符串就具有獨特的指針。爲了有效地對它們進行比較,你就必須使用isEqual:

if ([[someArray lastObject] isEqual:STRING_CONSTANT]) 
{ 
    ... 
} 

這可遠遠比單純==比較的執行時間方面的成本更高做字符一個字符比較。

另一個動機可能是可執行文件本身的大小。 #defined常量實際上會出現在適當的位置,無論它在代碼中使用何處。這可能意味着該字符串會在您的可執行文件中出現很多次。相比之下,常數應該(用現代編譯器)只定義一次,所有進一步的用法都會引用指向那個定義的指針。現在,在有人對我提出過早優化之前,我認爲兩種方法在實現方面幾乎完全相同,但是const指針方法在代碼大小和執行時間方面遠遠優於其他方法。

+0

我發現查克的答案與我的觀點相矛盾,我不確定誰是正確的。 – 2009-12-29 23:48:05

+1

常量不會在代碼中使用的地方出現。兩種方式都會生成對NXConstantString對象的引用。確實可以通過字符串文字來生成更多的字符串,但是對於代碼中的每個字符串字面量來說,它幾乎肯定會少於一個對象。 – Chuck 2009-12-29 23:50:45

+0

謝謝你。它幫助 – thesummersign 2012-12-03 04:35:18

9

我聽到的最好的說法是const字符串顯示在調試器中,而宏不顯示。

+0

這是一個很好的理由,你不能「po」(打印對象)#define'd指令。正如e.James指出的那樣,如果你的常量都是指針等價的,那麼你可以使用==來測試是否相等。 + 1的所有好的答案。 – pchap10k 2012-04-23 06:34:26

+0

是有意義的。 :) – thesummersign 2012-12-03 04:35:02

0
static NSString * const SERVER_URL = @"http://subdomain.domain.edu.ar/Folder/"; 
相關問題