2011-09-07 40 views
22
  1. 當使用時我的方法或變量聲明之前使用這個詞extern,我會使得它的全球和因此可讀/可寫/可用在整個項目中?3有關的extern問題在一個Objective-C項目

  2. 如果我在關鍵字之前使用了extern,有沒有可能仍然無法通過我的部分項目訪問它?例如,只有通過子類,例如當我使用「受保護」時。

  3. extern是C關鍵字,對吧?在Objective-C中是否有等價物?我實際上不明白他們爲什麼在Objective-C項目中使用C關鍵字。

感謝

+3

的Objective-C是C的超集。所以C關鍵字適用。 – Mat

+0

好問題.. – Krishnabhadra

+0

@Mat我知道,但我的觀點是:是不是objective-c提供自己的關鍵字來聲明全局變量的方法和變量? – aneuryzm

回答

37

1)你指定的聯動。外部鏈接允許您或任何客戶端引用該符號。關於全局變量:如果變量是可變的和/或需要適當的構造,那麼你應該考慮這個對象的方法或函數。在著名的例外是NSString的常數:

// MONClass.h 
extern NSString* const MONClassDidCompleteRenderNotification; 
// MONClass.m 
NSString* const MONClassDidCompleteRenderNotification = @"MONClassDidCompleteRenderNotification"; 

2)還有就是extern關鍵字影響可見性(公共/保護/私營/包),任何情況下。使用符號(例如常量或C函數),只需包含它聲明的頭文件。

如果您對該語言不熟悉,則會產生一些混淆:將extern C聲明(常量,函數)置於@interface ... @end之間不會改變其範圍:

@interface MONClass : NSObject 

extern const size_t MaximumThreads; 

@end 

具有相同的範圍(全局)和可見性(公共)爲:

@interface MONClass : NSObject 

@end 

extern const size_t MaximumThreads; 

所以它真的是沒有意義的將您的類相關的C常量或函數在@[email protected]@[email protected]。我建議在相同的標題作爲接口放置這些,外面@interface/@end@implementation/@end以及與它相關聯,像這樣的類前綴名稱:

@interface MONClass : NSObject 

@end 

extern const size_t MONClassMaximumThreads; 
// MONClass.m 
const size_t MONClassMaximumThreads = 23; 

,如果你想那個常數是私有的,只是聲明並定義是這樣的:

// MONClass.m 
static const size_t MONClassMaximumThreads = 23; 

@implementation MONClass 

@end 

不幸的是,有沒有同樣簡單或常見的方式,使這個常數與objc保護。

最後,您還可以使用類的方法,如果數量應有所不同類:

@interface MONMammal : NSObject 
+ (NSUInteger)numberOfLegs; 
@end 

@implementation MONDog 
+ (NSUInteger)numberOfLegs { return 4; } 
@end 
@implementation MONHuman 
+ (NSUInteger)numberOfLegs { return 2; } 
@end 

3)是的,在其他語言中。例如,如果在C++翻譯中使用extern const int Something,則C++翻譯將查找Something聲明爲外部C++符號。 objc中沒有替換; objc是C的超集,並且繼承了C的所有功能。使用extern的格式良好,您也可以在您使用的框架(例如Foundation)中找到它。他們使用它,因爲他們需要指定鏈接。 objc不提供替代品,大概是因爲它不需要替換或擴展。

避免這種情況,只需使用一個#define這樣的:

#if !defined(__cplusplus) 
#define MONExternC extern 
#else 
#define MONExternC extern "C" 
#endif 

MONExternC const size_t MONClassMaximumThreads; 
+2

A從類聲明的角度來看幾個音符:1),Objective-C中沒有'extern'方法; 2),並且與1)相關,它不適用於類層次結構。 – 2011-09-07 07:23:41

+0

@Bavarious嗯......我沒有指定方法是extern,只有*導出*。我明天會重讀 - 我已經很累了。它可能只是措辭不佳:)隨意編輯它,如果你喜歡。 – justin

+0

只是(希望!)使OP更清晰一點(並且在24小時清醒後,我甚至沒有考慮回答)。 – 2011-09-07 07:55:18

16

extern並不意味着 「全球」,它意味着 「定義別處」。它用於告訴編譯器存在一個變量或函數(在另一個目標文件或庫中),以便它不會抱怨它,並且鏈接器將與該目標文件或庫一起提供。

因此extern意味着目標項目是全局的。

Objective-C只是C的一個超集。C中可用的所有東西都可以在Objective-C中使用,並且具有相同的語法和語義。在Objective-C中沒有以另一種方式定義的C構造。

+0

謝謝。那麼,如果我想使用extern方法/變量,我是否總是需要導入包含extern語句的頭文件? – aneuryzm

+0

換句話說,我是否可以將我的extern方法/變量存儲在類中,並在需要使用它時導入它的頭文件?作爲替代方法,不能只使用靜態方法或來自單例的變量? – aneuryzm

+1

'extern'不適用於方法或實例變量,它適用於類的範圍之外的函數或變量。 – mouviciel

0

點3:是的,你可以使用FOUNDATION_EXPORT目標C這是一個解析爲不同的關鍵字取決於如果編譯C或C++

這裏更多的信息上的差異宏: "FOUNDATION_EXPORT" vs "extern"