有人可以向我解釋創建(似乎是)一個額外的變量的意義,以及爲什麼把一個下劃線放在與最後一個名稱相同的新變量之前。調用什麼是「@synthesize slider = _slider;」
我讀過它是關於創建實例變量,但爲什麼要創建一個UI元素作爲實例變量?你能提供一個用例嗎?
這個客觀的c代碼在iOS開發中使用。
謝謝。
有人可以向我解釋創建(似乎是)一個額外的變量的意義,以及爲什麼把一個下劃線放在與最後一個名稱相同的新變量之前。調用什麼是「@synthesize slider = _slider;」
我讀過它是關於創建實例變量,但爲什麼要創建一個UI元素作爲實例變量?你能提供一個用例嗎?
這個客觀的c代碼在iOS開發中使用。
謝謝。
這樣做的原因是爲了使實例變量清楚地從屬性打點語法中脫穎而出。它還具有避免參數名稱映射實例變量的實際效果,這在某些情況下也會發生。
在大多數情況下使用實例變量的原因是爲了避免在dealloc中觸發KVO。如果你這樣做,你可能會觸發KVO,讓你的觀察者得到一個傳遞給它們的釋放對象,導致EXC_BAD_ACCESS。
- (void)dealloc
{
self.slider = nil;
[super dealloc];
}
因此,通常這樣做,而不會觸發KVO,因爲您不進行屬性訪問。
- (void)dealloc
{
[_slider release];
[super dealloc];
}
這是通常用於合成私人前綴或後綴伊娃的財產。它試圖防止你意外地訪問伊娃而不是屬性或用方法參數覆蓋伊娃。
考慮一下:
@implementation MYClass
@synthesize flag = flag_;
- (void)doSomethingWithFlag:(BOOL)flag {
if (flag) {
// You do not need to worry about confusing the ivar
// flag and the param flag because it is synthesized to flag_
}
}
- (void)doSomething {
if (flag) { // Doesn't work -> use accessor self.flag
...
}
}
@end
當你@synthesize
一個屬性,你不提供自己的getter和setter方法(在這種情況下沒有必要@synthesize
),那麼總有一個新的實例變量,創建。默認情況下,它獲得與該屬性相同的名稱。所以@synthesize slider;
在幕後製作了一個名爲slider
的實例變量。
這裏的問題是,如果您真的打算使用self.slider = xxx
,您可能會錯誤地鍵入slider = xxx
。當您創建某個屬性時,最佳實踐表示您應該始終通過self.propertyName
訪問它(除了init和dealloc方法以及任何自定義getter和setter方法)。
因此,爲了避免這種情況,使用@synthesize
語句將支持ivar重命名爲難以與屬性混淆的東西。如果您現在使用slider
而不是self.slider
,編譯器將提供錯誤消息,因爲slider
不再是實例變量的名稱。
「當你製作某個屬性時,最佳實踐表明你應該總是通過self.propertyName訪問它」 - 爲什麼這是最佳實踐? – Ger
因爲這是屬性背後的一點,所以你總是通過它們的訪問器方法。通過直接訪問ivars,您可以繞過該行爲。 – Hollance