2011-10-31 37 views
19

我有一個iOS應用程序,從一開始就有一個錯誤。由於源是開始從模板構建,其appdelegate.h樣子:無法在@interface或@protocol中聲明變量

@interface myAppDelegate : NSObject <UIApplicationDelegate> { 
    UIWindow *window; 
    myViewController *viewController; 
} 

BOOL  myBool;  // intended to be globally accessible 
NSString *myString; // intended to be globally accessible 

@end 

我是指很多其他的.m源文件myBool* myString的,爲全局變量。

在XCode 3.2.6下面,我不記得在編譯時遇到任何問題。

在3.2.6,在編譯時出現警告,指向appdelegate.h中的這些「全局」變量,並說:「無法在@interface或@protocol中聲明變量」。由於編譯或應用程序運行時沒有其他問題,所以不幸的是我沒有考慮這些警告。

現在,使用XCode 4.2,我無法編譯這個源代碼,因爲前面的警告變成了構建錯誤。他們引用並指向每個不同的.m文件中有「全局變量」引用的行。

考慮到我仍然想將這些變量/引用作爲全局變量或引用來訪問,是否有一種簡單的方法可以糾正這個問題?

其它問題:如果這個爲什麼沒有預警低於XCode的v3.2.6給出任何想法,只是警告3.2.6:當我評價迄今收到的答案(感謝各位),另一個問題從我身邊來說是一個真正的錯誤?爲什麼代碼仍然編譯並且可以毫無問題地運行?

+0

作爲一個忠告,在這個意義上的「全局」變量通常是一個壞主意在面向對象編程中,因爲它們違背了局部性和封裝性。網上有很多關於這個主題的在線閱讀。 –

回答

30

他們不能去那裏。你可以把它們放在大括號{}中,像這樣:

@interface myAppDelegate : NSObject <UIApplicationDelegate> { 
    UIWindow *window; 
    myViewController *viewController; 
BOOL  myBool;  // intended to be globally accessible 
NSString *myString; // intended to be globally accessible 
} 

@end 

而這使得它們成爲實現類的全局。但是,如果你希望他們全球在應用程式中每一個類,那麼你應該把它們在你的App-Prefix.pch文件:

// 
// Prefix header for all source files of the ... project 
// 
#import <Availability.h> 
BOOL  myBool;  // intended to be globally accessible 
NSString *myString; // intended to be globally accessible 
#ifndef __IPHONE_3_0 
+1

我最終做的是創建一個單獨的「global_variables.h」文件,將所有這些變量放入它並使用#import將其包含在appdelegate.h中,並且它可以工作! :) – cactusdev

+0

這是老實說,我見過的最醜陋的語法組合。我知道它是預編譯器的標誌,但它是如此混亂。 – Sirens

1

C全局變量應該在.m實現文件中聲明,而不是在.h頭文件中聲明。一個extern聲明可以放在.h頭文件中,通常在包含和聲明之外。

將全局對象指針初始化爲零也是一種很好的做法,否則它們可能會包含垃圾對象引用。

3

編譯器正在抱怨@interface塊中的變量,因此請將它們移出它,或者高於@interface或低於@end。你實際上可能想在頭文件中將它們改爲externs,並實際在.m文件中聲明它們。

10

你是否試圖將它們定義爲一個類的公共成員? Objective-C中的類與您可能熟悉的其他語言中的類非常不同。花括號之外,你只能定義方法。如果你想使公衆可訪問的成員,它們定義爲屬性:

@interface myAppDelegate : NSObject <UIApplicationDelegate> { 
    UIWindow *window; 
    myViewController *viewController; 
    BOOL _myBool; 
    NSString *_myString; 
} 

@property BOOL  myBool;  // intended to be globally accessible 
@property NSString *myString; // intended to be globally accessible 

@end 

然後在你的@implementation做這樣的事情:

@implementation myAppDelegate 
@synthesize myBool = _myBool; 
@synthesize myString = _myString; 

然後你就可以訪問它們作爲myObject.myBool等。

如果你只是試圖讓他們變成類的所有實例的靜態(「環球」)的數據,那麼其他海報說,你要定義移動到您的.m文件(理想情況下宣佈他們static所以他們不會造成鏈接問題)。

+0

我試圖讓它們可用於項目中的所有類(這就是爲什麼我說「全局」)。所以我想讓它們可以從所有.m文件訪問。 – cactusdev

+2

好吧,那麼你長期以來想要做的事情是把它們放在任何'@interface'等外面的.h文件中,並聲明它們是'extern',然後有一個匹配的源文件來聲明變量本身(沒有任何修飾符)。如果你在.h中聲明瞭非extern屬性,那麼你可能會遇到鏈接問題。 – fluffy