2010-12-07 54 views
4

在現代的Objective-C運行時,你可以做這樣的事情:什麼時候你不想使用@synthesized實例變量?

@interface MyClass : NSObject { 
} 
@property NSString *stringProperty; 
@end 

@implementation MyClass 
@synthesize stringProperty; 
@end 

這是我的理解與現代的運行,這將不僅合成的訪問者爲我的財產,而且該實例變量本身,所以我可以在這個類的方法[stringProperty length];之一中說,它會像我聲明一個實例變量一樣工作。

我已經開始在我的所有代碼中使用它了,因爲它是我不得不一遍又一遍地重複寫的東西。我聽說過使用clang 2.0編譯器,我甚至可以跳過@synthesize(但這是另一回事)。但我一直在想,做這件事有什麼缺點?什麼時候可以真正需要一個實例變量以及我的屬性?

我知道有時候我想保留一個變量private並且不允許在外部訪問它(但是我通常只是在我的私有類擴展中聲明該屬性,或者我不爲它創建屬性所有,如果我不需要訪問器)。

有沒有什麼時候我不想這樣做?

+0

@joe是的,如果我要聲明屬性並如上所述合成它,但我沒有明確地聲明自己的ivar,編譯器仍然會實際創建ivar。所以我可以在類中做'int len = [self.stringProperty length]`,而且我也可以`int len = [stringProperty length]`,而不使用accessor方法,直接使用ivar(編譯器爲我合成的,以及setter + getter)。這真的太棒了! – jbrennan 2010-12-08 19:34:43

+0

@joe我從檢查存根XCode4現在爲應用程序委託生成了解這一點。 – 2011-04-11 21:39:00

回答

4

爲什麼建議不使用綜合實例變量是一個可能的原因是他們在當前版本的Xcode(3.2.5)中調試有點麻煩。當通過GDB運行代碼時,它們似乎並不出現在實時調試器視圖中,唯一的方法是通過gdb控制檯,如po [0xOBJ_ADDRESS propertyName]。不像一個標準的非合成伊娃。

也許Xcode 4修復了這個問題,但是我沒有足夠的經驗來說(它還在NDA下)。

在這太問題更多信息:Seeing the value of a synthesized property in the Xcode debugger when there is no backing variable

3

您可能需要提供一種用於單個實例變量的許多特性,例如:

  • 用於訪問無論是在度和弧度
  • 用於訪問無論是在矩形的,並且在極性體系
  • 座標的角度值

在這些情況下,您不希望綜合實例變量(它已經存在)或訪問器方法(您希望爲它們提供轉換)。

+1

當然,但這與編譯器合成實例變量沒有任何關係。讓我們說,而不是我的`stringProperty`我改爲使用'float angleInDegrees`屬性。因此,這將合成一個伊維爾角度度量,我可以添加第二個(只讀)屬性,將其轉換爲弧度並返回。除非我錯過了某些東西,當然。 – jbrennan 2010-12-07 21:16:05

+0

第二個屬性不需要只讀:如果要編寫以弧度表示的值,該怎麼辦?只需添加一個`@property float angleInRadians`,不要`@合成'它,並提供在兩個方向上執行轉換的存取器方法。 – mouviciel 2010-12-07 21:23:24

1

無論何時您需要進行轉換(除非有人知道更好的方法),您需要序列化一個類。例如,如果您有一個具有數值的類。你不能序列化一個整數,所以你把它作爲一個NSNumber存儲在這個類中,但是這個屬性是一個整數類型。

另一個例子是,如果你使用CoreData處理Apple建議的代碼。他們說你應該創建一個從NSManagedObject派生的自定義類作爲你的託管對象的類,併爲每個屬性使用一個屬性。然後你會使用@dynamic而不是@synthesize,並且根本不需要iVar。

+0

`[coder encodeInteger:someIntVar forKey:@「myIntKey」];`不是爲你做的嗎? – jbrennan 2010-12-07 21:13:32

+0

這就是爲什麼我說「除非有人知道更好的方式」。如果需要,我會記住你的代碼。 :-) – Rob 2010-12-07 23:13:58

0

的另一個原因是爲了避免快捷鍵直接變量訪問。

我嘗試按照個人編碼約定: - 對象變量:前綴下劃線「_xxx」 - 財產:無下劃線命名爲「XXX」

這確保我從來不寫無意像

xxx = value; 

[xxx someMessage]; 

我要永遠使用的getter/setter。

self.xxx = value; 
[self.xxx someMessage]; 

當您使用對象變量延遲初始化這是特別有用...

1

但我一直在想,是什麼的一些缺點,以這樣的?什麼時候可以真正需要一個實例變量以及我的屬性?

可能的原因:

  • 它可以讓你改變initdealloc實例變量沒有絆倒子類覆蓋或志願。
  • 該應用程序將在Mac OS X上以32位模式進行編譯和運行。還有一些不支持64位的英特爾Mac。

我不確定第一點真的有多有效。這些問題可能還有其他解決方法。第二點是遊戲結束,但如果你需要支持較老的Mac。

相關問題