2012-08-12 80 views
0

我有MyUnitClass宣佈像這樣實現:爲什麼這些「成員」變量的行爲像靜態?

@implementation MyUnitClass 
Unit* _unit = NULL; 

在for循環中,我迭代的次數和創建MyUnitClass的多個實例。 Unit表現得像一個靜態變量。我有一個斷點MyUnitClass init方法內設置,這是每一個類initalized時間我得到什麼:

(gdb) print _unit 
$4 = (Unit *) 0x112340 
(gdb) print _unit 
$5 = (Unit *) 0x112340 

注:

我已經變量移動到已經解決了這個問題聲明@interface。如果你回答了這個問題,那麼看到一個可以找到這個信息的頁面的鏈接就太棒了。

+2

Objective-C沒有成員變量;它有實例變量。或多或少都是一樣的,但命名的一致性有所幫助。 – bbum 2012-08-12 06:05:52

回答

3

正如Richard指出的那樣,缺少大括號將var定義爲全局變量。在聲明實例變量方面,有幾種方法:

Objective-C Programming Language中討論了在@interface@implementation中聲明實例變量。

所以,你可以在@interface,這是你在歷史上將會看到的實例變量定義的最常見的地方定義一個實例變量x

@interface TestClass : NSObject 
{ 
    NSInteger x; 
} 
@end 

@implementation TestClass 

// define the methods 

@end 

正如上面的鏈接描述,但是,你也可以在@implementation定義它(雖然,因爲習慣問題,我不認爲你會看到這個非常頻繁):

@interface TestClass : NSObject 

@end 

@implementation TestClass 
{ 
    NSInteger x; 
} 

// define the methods 

@end 

其實是有,你可以把你的實例變量一個第三名,在課程擴展中(稍後在same document中討論)。在實踐中,這意味着你可以有你的.h定義如下

// TestClass.h 

@interface TestClass : NSObject 

// define public properties and methods here 

@end 

和您的m如下:

// TestClass.m 

// this is the class extension 

@interface TestClass() 
{ 
    NSInteger x; 
} 
@end 

// this is the implementation 

@implementation TestClass 

// define the methods 

@end 

這最後一種方法(與@interface一.H,用類.M擴展名和@implementation)現在是Xcode模板在創建新類時使用的格式。實際上,這意味着您可以將公共聲明放在.h文件中,並將您的私有@property和實例變量放入類擴展中。它只是讓你的代碼更清潔一些,使你不需要使用私有實現細節來混淆你的.h文件(這實際上就是你的類的公共接口)。例如變量,或許在@implementation中定義實例變量的先前技術是等價的,但我認爲它不適用於@property聲明,在這種情況下,類擴展會變得有用。

+0

實際上如果你有一個UIKit元素的子類,比如'UIViewController',Xcode只使用類擴展變體。但是,看到有多少人只是在他們的應用中劃分子類,這是一個很容易犯的錯誤。 – 2012-08-12 13:22:04

+0

@ RichardJ.RossIII嗯,它只會自動爲UIKit子類添加一個空白的類擴展?我沒有注意到這一點。但是,顯然,你可以使用任何你想要的類的類擴展。 – Rob 2012-08-12 14:11:50

8

這是因爲你沒有用花括號包圍變量,使它成爲一個全局變量。要修復,嘗試將其定義是這樣的:

@implementation MyObject { 
    unsigned int myVar; 
} 

// rest of implementation 

@end 

只能有一個@implementation塊,所以如果是在.h文件中已經聲明,那麼成員將需要在此進行添加或整個塊將需要移動到.m文件。

這是C語言的一個補遺,編譯器並不完全知道你希望它是一個iVar,而不是全局的。

+0

我也見過這種表示法(在實現大括號的外側):@synthesize preferences = __ preferences。我猜在這種情況下,它是一個普通的老成員,而不是全球性的。 – Brian 2012-08-12 01:02:56

+0

@rhooligan'@ synthesize'稍有不同,屬性實現指令。引用[Objective-C編程語言](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html#//apple_ref/doc/uid/TP30001163- CH17-SW9):「你可以使用'@ synthesize'指令告訴編譯器,如果你沒有在@ @ implementation'塊中提供它們,它應該爲一個屬性合成setter和/或getter方法。'@synthesize '指令還會合成一個適當的實例變量,如果它沒有被另外聲明。「 – Rob 2012-08-12 09:07:18

相關問題