2012-03-03 14 views
13

Jaka jest rzeczywista nazwa zmiennej instancji, powiedzmy, topSpeed, jak z wykładów na Uniwersytecie Stanforda dotyczących programowania Objective-C i iOS?Właściwość Objective-C i logika syntezy

Oto kod:

@property (nonatomic) double topSpeed; 

Patrząc na ten kod będę myśleć, że zdefiniowano zmienną Topspeed w klasie. Nie mogę zrozumieć, dlaczego automatycznie zadeklaruje metodę getter z nazwą taką samą jak nazwa zmiennej - topSpeed?

Inną kwestią jest to, gdy używamy

@synthesize topSpeed = _topSpeed 

A jeśli spojrzymy na to, co @synthesize wygeneruje:

- (double) setTopSpeed:(double)speed 
{ 
    _topSpeed = speed; 
} 


- (double) topSpeed 
{ 
    return _topSpeed; 
} 

Co _topSpeed ​​tutaj, a co Topspeed? Zadeklarowałem zmienną topSpeed, a nie _topSpeed. Co się stanie, jeśli nie będę używał własności, jaka byłaby nazwa zmiennej?

+0

http://stackoverflow.com/questions/3521254/prefixing-property-names-with-an-underscore-in-objective-c – Saurabh

Odpowiedz

36

W poprzednich dniach Obj-C i jeszcze dzisiaj ogłosił zmienne w pliku nagłówkowym klasie jest tak:

@interface MySubclass : NSObject { 
    int varName; 
} 

Wtedy trzeba ręcznie utworzyć setter i getter metod do uzyskać dostęp do zmiennej poza twoją klasą. Aby pomóc w zarządzaniu pamięcią (przydatne dla obiektów), firma Apple wprowadziła właściwości w Obj-C 2.0 i umożliwiła zdefiniowanie akcesorów dla danej zmiennej. Można powiedzieć, że zmienna będzie mieć pewne cechy (takie jak zatrzymanie lub kopiowanie wartości, mając alternatywnego setter getter lub nazwę, etc) i zdefiniowano to tak:

@property (someAttributes) int varName; 

następnie w @implementation można @synthesize te właściwości z podanymi atrybutami i kompilatorem generowałyby metody ustawiające i pobierające dla zmiennej.

@synthesize varName; // Generates -setVarName: and -varName for you 

Teraz, dziś chodzi o to, że można odejść od realizacji zmiennych instancji w sekcji {} i po prostu zadeklarować właściwości i syntetyzować. Co otrzymamy, jeśli po prostu powiedzieć

@property (nonatomic) double topSpeed; 
@synthesize topSpeed; 

jest setter i getter nazywa setTopSpeed ​​a Topspeed z zmiennej instancji o nazwie Topspeed (utworzony przez kompilator), aby zapisać wartość. Ideą @synthesize topSpeed = _topSpeed; jest to, że nazwa zmiennej instancji będzie miała nazwę _topSpeed, ale nazwy akcesorów będą nadal następujące: -setTopSpeed: i -topSpeed. Pomaga to w czytelności kodu, ponieważ może występować niejasność, gdy w swoim kodzie wypowiada się self.topSpeed ​​lub topSpeed ​​(pierwsze wywołania, a drugie to ivar). _topSpeed ​​odróżnia się od normalnych zmiennych i czyni je wyraźnym, gdy wywołujesz self.topSpeed ​​(akcesor) vs _topSpeed ​​(ivar). Apple również przechodzi do tej składowej podkreślenia, więc nie myśl, że wygaśnie, ponieważ jest zupełnie odwrotnie. Aktualizacja: (patrz komentarz Tommy'ego)

Pomaga również w przypadku kolizji zmiennych nazw. Jeśli trzeba było wdrożyć setTopSpeed: samemu to wyglądać mniej więcej tak:

setTopSpeed:(double)topSpeed { 
    _topSpeed = topSpeed; // _topSpeed makes it obvious it's an ivar 
} 
+11

... a obecnie '@synthesize topSpeed ​​= _topSpeed' jest implikowany przez powiązaną właściwość @; nie ma potrzeby go włączać. Możesz dołączyć alternatywną '@ synthesize' (np. Aby określić nazwę zmiennej instancji bez wiodącego podkreślenia lub zupełnie niezwiązaną z tą właściwością) lub samodzielnie zapisz komendę getter/setter (np. Jeśli chcesz wywołać, powiedz:' [ self setNeedsLayout] 'gdy właściwość się zmienia), ale jeśli nic nie dostarczysz, kompilator wywnioskuje zwykłą' @ synthesize'. – Tommy

+0

_self.topSpeed ​​lub topSpeed ​​w twoim kodzie (które są 2 różnymi rzeczami) _ Czy te dwie różne rzeczy, ponieważ 'topSpeed' jest zmienną instancji, której wartość jest zwracana przez właściwość' self.topSpeed'? – Trisped

+0

@ Tisłem I zaktualizowałem tę linię. Powinno być teraz jasne. –

0

Na pierwsze pytanie odpowiedź brzmi "konwencja nazewnictwa". Jest to więc tylko konwencja nazewnictwa. Jeśli chcesz uzyskać dostęp do zmiennej topSpeed, część "get" nie jest znacząca - podobnie jak [car topSpeed] jest łatwiejsza do odczytania niż [car getTopSpeed]. Jeśli chodzi o drugie pytanie, nie jestem pewien, ale uważam, że dostęp do właściwości topSpeed za pośrednictwem zmiennej _topSpeed.

3
  1. Jest to cukier składnia, niech wpiszesz mniej słowo.
  2. W przeciwieństwie do java/C++, w obj-c nie można uzyskać dostępu do zmiennej klasy. Można tylko nazwać metody It.
  3. oznacza Chcesz zmiennej o nazwie _topSpeed ​​i ma Accessors o nazwie topSpeed ​​i setTopSpeed.
  4. @property (nonatomic) double topSpeed; jest nie deklaracja czysto zmienna, zadeklaruje także Akcesoriów. Czysta zmienna klasy Foo będzie wyglądać następująco:

    @ interfejs Foo: NSObject { double topSpeed; }

+1

"W przeciwieństwie do java/C++, w obj-c nie można uzyskać dostępu do zmiennej klasy." Jeśli masz na myśli zmienne instancji, możesz uzyskać do nich bezpośredni dostęp w Objective-C, jeśli są to "@ public". –