2013-11-14 34 views
1

我已經閱讀過有關這個問題的不同來源:書籍,文章等,但無法理解它。你能否舉一個例子來說明支持i-vars和屬性的問題,以及如何解決它? 我從這裏閱讀了下面的代碼http://blog.bignerdranch.com/463-a-motivation-for-ivar-decorations支持的實例變量和屬性的示例。它是否與「自我」相關?

@property (copy) NSString *name; 
... 
@synthesize name; 
... 
- (void) setPonyInfoFromPropertyDict: (NSDictionary *) ponyProperties { 
    NSString *name = [ponyProperties objectForKey: @"Name"]; 
    ponyName = name; //self.ponyName=name should solve the problem? 
} 

NSMutableString *mutableName = [NSMutableString stringWithString: @"Mikey"]; 
NSDictionary *ponyProperties = [NSDictionary dictionaryWithObject: mutableName 
           forKey: @"Name"]; 
[pony setPonyInfoFromPropertyDict: ponyProperties]; 
[mutableName setString: @"Wookiee"]; 

該代碼和文章是否與此問題相關? 正確的方法是使用self.ponyName = name?在任何其他設置方法?

回答

1

我相信這個例子是錯誤的或者是不合適的。一個適當的例子應該是

@property (copy) NSString *ponyName; // not name! 
... 

@synthesize ponyName; // not name! 
... 
- (void) setPonyInfoFromPropertyDict: (NSDictionary *) ponyProperties { 
    NSString *name = [ponyProperties objectForKey: @"Name"]; 
    ponyName = name; 
    //self.ponyName = name; // will solve the problem 
} 

name可以是一個可變的字符串,所以如果你想確保它不會改變已分配後,你必須複製它。您可以使用copy屬性的任務,但你不使用的setter都做

ponyName = name; 

self.ponyName = name; 

將修復問題並且name將被設置者複製。


探討

其中最常見的錯誤時在Objective-C的編程是訪問的ivar直接代替使用設置器/吸氣劑。

配件方法很重要,因爲它們通常提供了很多訪問和設置ivars的邏輯,最值得關注的是內存管理。現在,ARC編譯器大大簡化了它們的實現,但是,如果您使用MRC,配件方法對於幫助處理餘額至關重要。

在ARC下仍然有效的示例是聲明copy屬性。在這種情況下,合成的二傳會照顧參數複製的分配給伊娃之前,所以當你

[self setMyCopyProperty:aNewThing]; 

或等價

self.myCopyProperty = aNewThing; 

aNewThing將收到一個copy消息,被分配到前支持的伊娃。

在另一方面,如果你合成的屬性這樣

@synthesize myCopyProperty; 

你可能會意外地發現自己做

myCopyProperty = aNewThing; 

,不會複製aNewThing,因爲你是直接訪問伊娃。

爲了不混淆ivars和配件方法,它成爲一個標準約定,在ivars前加下劃線,即綜合他們像

@synthesize myCopyProperty = _myCopyProperty; 

這樣,如果你不小心做

myCopyProperty = aNewThing; 

不能編譯,因爲作爲一個myCopyProperty伊娃沒有這樣的事情,可能是從一個可怕的頭痛節省你當你是調試內存相關的問題。相反,如果你知道自己在做什麼,你真的要訪問的伊娃(也許在init法),你可以簡單地做

_myCopyProperty = [aNewThing copy]; 

這是很多你不使用二傳手的意圖更加明確。

最後,它可能是值得注意的是,與clang編譯器的現代版本可以避開明確@synthesize,因爲它會在

@synthesize foo = _foo; 

有些例外適用的形式自動插入,你可以閱讀更多關於它在這裏:When should I use @synthesize explicitly?

+0

謝謝,現在我明白,伊娃只是分配給可變的變種,這可以在將來改變。所以需要複製? 但是,支持的問題是什麼?什麼是「支持」? – user2553675

+0

'支持伊娃'只是簡單地表明該物業爲您提供的ivar,該物業的最後一個例子是'foo',並且由伊娃'_foo'支持。 –

相關問題