我一直在尋找常量,並且我不明白他們有什麼不同,除非他們不能以編程方式更改。常數的解釋
extern NSString * const MyConstant;
這條線究竟是什麼意思extern
,準確地什麼的const
是什麼意思?
我一直在尋找常量,並且我不明白他們有什麼不同,除非他們不能以編程方式更改。常數的解釋
extern NSString * const MyConstant;
這條線究竟是什麼意思extern
,準確地什麼的const
是什麼意思?
有人問你兩個問題:一個關於常量,一個關於extern。這兩者不一定相關。
首先,const:沒有太多的常量比,正如你所說的,它們不能以編程方式改變。取決於你如何聲明它們,不同的事物可以是不變的。例如,在你的例子中:
NSString * const MyConstant = @"foo";
你已經聲明瞭一個常量指針,指向一個非常量的NSString對象; const
關鍵字位於星號的右側,因此它指向指針。因此,這樣的:
MyConstant = @"bar";
將導致編譯錯誤,因爲它試圖重新分配MyConstant
指向一個不同的NSString。
如果const
關鍵字位於星號的左側,它將引用指針引用的對象(在本例中爲底層NSString結構體)。這可能不是你最想要的目的C.時間請注意,相對於類型標識符const
關鍵詞的位置並不重要,所以這樣的:
const NSString *MyConstant = @"foo";
這:
NSString const *MyConstant = @"foo";
表示同樣的事情。您也可以合法地申報指針和參考價值常量兩者最大常量性:
const NSString * const MyConstant = @"foo";
其次,EXTERN:extern
只是允許您在一個編譯單元聲明一個變量,並讓編譯器知道您已經在單獨的編譯單元中定義了該變量。你通常只用於全局值和常量。
您可以將編譯單元視爲單個.m
文件,以及它包含的所有.h
文件。在編譯時,編譯器會將每個.m文件編譯爲一個單獨的.o
文件,然後鏈接器將它們全部掛接到一個二進制文件中。通常,一個編譯單元知道另一個編譯單元中聲明的標識符(例如類名)的方式是導入一個頭文件。但是,對於全局變量,它們通常不是類的公共接口的一部分,所以它們經常在.m
文件中聲明和定義。
如果編譯單元中聲明瞭一個全球性的.m
文件:
#import "A.h"
NSString *someGlobalValue;
和編譯單元B想要使用全球:
#import "B.h"
extern NSString *someGlobalValue;
@implementation B
- (void)someFunc {
NSString *localValue = [self getSomeValue];
if (localValue isEqualToString:someGlobalValue]) {
...
}
}
單元B以某種方式告訴編譯器使用由單元A聲明的變量。它不能導入發生聲明的.m
文件,所以它使用extern
告訴編譯器該變量存在於其他地方。
注意,如果單元A和單元B 都有這條線在文件的頂層:
NSString *someGlobalValue;
那麼你有兩個編譯單元聲明相同的全局變量,鏈接器將失敗有重複的符號錯誤。如果你想有一個像這樣只存在編譯單元裏面,是看不到任何其他的編譯單元(即使他們使用extern
)一個變量,你可以使用static
關鍵字:
static NSString * const someFileLevelConstant = @"wibble";
這可以用於您想在單個實現文件中使用的常量,但不需要其他位置。
Extern表示該變量設置在聲明的源文件之外。建議使用OBJC_EXPORT標誌而不是extern。
const表示變量設置後無法更改。但是,你可以使用一些指針誤導,如下圖所示:
NSString **var = (NSString **)&MyConstant;
*var = @"I changed it!";
這實際上將讓你改變它,如果你需要(例如,在你的類+initialize
法)。
第一段有意義。其餘與這個問題無關(並且沒有意義)。 – bbum 2010-12-04 17:16:12
extern NSString * const MyConstant;
你會在頭文件中看到這個。它告訴編譯器,變量MyConstant
存在並且可以在你的實現文件中使用。
多不容易,該變量設置是這樣的:
NSString * const MyConstant = @"foo";
值不能被改變。如果您想要一個可以更改的全局,則從聲明中刪除const
。
你應該很少看到頭文件中的`extern`。存在`extern`關鍵字以允許鏈接程序解析跨翻譯單元使用的符號。如果符號在頭文件中聲明,則不需要使用`extern`;只需導入頭文件。而且,由於全局變量不是類的接口的一部分,因此不需要使用`extern`將一個符號導入到頭文件中。 – 2010-12-04 19:55:55
給那些打破它的人歡呼。分解它。 – 2012-09-30 19:47:00