2010-04-03 134 views
35

我是Objective-C的新手,但我很好奇我在其他任何地方都未見過的東西。在@implementation而不是@interface中定義的類變量?

誰能告訴我是什麼,是在@interface塊與所聲明的@implementation塊內的類方法之外的變量聲明爲私有變量,即區別:

@interface Someclass : NSObject { 

NSString *forExample; 

} 

@end 

@implementation Someclass 

NSString *anotherExample; 

-(void)methodsAndSuch {} 

@end 

看來這兩個變量(forExampleanotherExample)是整個階級平等開放,我真的不能找到他們行爲上的差異。第二種形式也稱爲實例變量?

回答

25

後者沒有定義實例變量。相反,它是在.m文件中定義一個全局變量。這樣的變量不是唯一的或任何對象實例的一部分。

這種全局有其用途(大致相當於C++靜態成員;例如存儲單件實例),但通常你會在該文件的@implementation指令之前頂端定義它們。

+0

這是我懷疑你的答案非常有意義,但如果我嘗試訪問任何其他類中的anotherExample'(通過正確地在這些類中包含'Someclass'),編譯器告訴我這個變量是未聲明的。是什麼賦予了? – bitcruncher 2010-04-03 15:04:08

+3

@bitcruncher,因爲'anotherExample'僅對聲明它的.m文件是全局的。如果你希望它可用於其他文件,那麼你必須在.h文件中聲明'extern NSString * anotherExample;',然後在你需要全局的地方''導入'.h文件。儘管它具有有效的用例,但是這種代碼異味仍然存在。 – 2010-04-03 15:26:28

+4

沒有實際的代碼聞:-)這只是一個探索性問題。 – bitcruncher 2010-04-03 16:05:43

4

如果聲明的@implementation段中的變量,你實際上是創建一個全局變量,隨處可見(在每一個方法在應用程序)。

成員變量只能在@interface部分中聲明。他們只能在課堂上訪問。

21

他們非常不同! @implementation中的那個是不是每個實例唯一的全局變量。想象一下,有兩個變量的訪問器,以明顯的方式編寫。然後,在行爲的差異如下所示:

Someclass* firstObject = [[Someclass alloc] init]; 
Someclass* secondObject = [[Someclass alloc] init]; 

//forExample is an instance variable, and is unique to each instance. 
[firstObject setForExample:@"One"]; 
[secondObject setForExample:@"Two"]; 
NSLog(@"%@",[firstObject forExample]); //Result: "One" 
NSLog(@"%@",[secondObject forExample]); //Result: "Two" 

//anotherExample is a global variable, and is NOT unique to each instance. 
[firstObject setAnotherExample:@"One"]; 
[secondObject setAnotherExample:@"Two"]; 
NSLog(@"%@",[firstObject anotherExample]); //Result: "Two" (!) 
NSLog(@"%@",[secondObject anotherExample]); //Result: "Two" 

//Both instances return "Two" because there is only ONE variable this time. 
//When secondObject set it, it replaced the value that firstObject set. 

如果您正在尋找這樣的行爲,你可能會更好使用類變量,就像這樣:

static NSString* yetAnotherExample = nil; 

然後你可以使用類方法與變量進行交互,並且它顯然是類特定的(而不是實例特定的或全局的)。

+0

那麼'anotherExample'是一個程序範圍的全局變量還是一個類的全局變量?換句話說,'anotherExample'是一個存在_always_的全局變量,或者是當'Someclass'被實例化時存在的全局變量? – bitcruncher 2010-04-03 15:08:03

+1

它存在* always *。你可以在另一個.m文件中聲明'extern NSString * anotherExample'並再次使用它。請不要。但你可以。 :P – andyvn22 2010-04-03 15:31:36

+0

請不要以爲我是這樣編碼的。 :-)試圖理解爲什麼其他人這樣做(例如iPhone的厄運) – bitcruncher 2010-04-03 16:09:53

0

只要是明確的,永遠不聲明一個IBOutlet作爲一個全局變量(在執行),如果您使用的是它爲局部筆尖/ xibs。

我花了幾個小時搞清楚爲什麼出口僅在任何給定的時間本地化碎粒的一個連接。

感謝這個問題和答案!

3

@implementation塊內聲明的專用塊是種危險的,在我看來,與其他OOP概念例如比較Java的。它看起來像成員變量,但有點靜態。

新手程序員可以很容易地欺騙它。我寫了一個測試程序,並對行爲感到驚訝。

@interface SomeClass : NSObject 
{ 
    NSString *forExample; 
} 

- (void) set:(NSString *)one another:(NSString *)another; 
- (void)print; 

@end 

實現:

#import "SomeClass.h" 

@implementation SomeClass 

NSString *anotherExample; 

- (void) set:(NSString *)one another:(NSString *)another 
{ 
    forExample = one; 
    anotherExample = another; 
} 

- (void)print{ 
    NSLog(@"One = %@, another = %@", forExample, anotherExample); 
} 

@end 

測試:

- (void)testClass { 
    SomeClass * s1 = [SomeClass new]; 
    [s1 set:@"one one" another:@"one another"]; 
    SomeClass *s2 = [SomeClass new]; 
    [s2 set:@"two one" another:@"two another"]; 
    [s1 print]; 
    [s2 print]; 
} 

和輸出是,

One = one one, another = two another 
One = two one, another = two another 
相關問題