W kilku przykładach iPhone'a widziałem, że atrybuty używają podkreślenia _ przed zmienną. Czy ktokolwiek wie, co to znaczy? Albo jak to działa?
Plik interfejsu, którego używam, wygląda następująco:
@interface MissionCell : UITableViewCell {
Mission *_mission;
UILabel *_missionName;
}
@property (nonatomic, retain) UILabel *missionName;
- (Mission *)mission;
Nie jestem pewien, co dokładnie robi powyższe, ale kiedy próbuję ustawić nazwę misji, taką jak:
aMission.missionName = missionName;
Wyskakuje mi błąd:
prośba o członkostwo „MissionName” w czymś, co nie jest strukturą ani związkiem
property
w pliku .h oraz w .m FIE mam dostępu do niego przy użyciuself
jak takself.someProperty
. Czy to dobra droga? A może powinienem używać ivars w kodzie?To tylko konwencja czytelności, nie robi nic specjalnego dla kompilatora. Zobaczysz, jak ludzie używają go na prywatnych zmiennych instancji i nazwach metod. Apple faktycznie nie zaleca używania podkreślenia (jeśli nie jesteś ostrożny, możesz zastąpić coś w swojej superklasie), ale nie powinieneś czuć się źle, ignorując tę radę. :)
źródło
Jedynym użytecznym celem, jaki widziałem, jest rozróżnienie między zmiennymi lokalnymi i zmiennymi składowymi, jak wspomniano powyżej, ale nie jest to niezbędna konwencja. W połączeniu z @właściwością zwiększa szczegółowość instrukcji syntetyzujących -
@synthesize missionName = _missionName;
i wszędzie jest brzydki.Zamiast używać podkreślenia, po prostu używaj opisowych nazw zmiennych w metodach, które nie powodują konfliktów. W przypadku konfliktu nazwa zmiennej w metodzie powinna zawierać podkreślenie, a nie zmienną składową, która może być używana przez wiele metod . Jedynym typowym miejscem, w którym jest to przydatne, jest setter lub metoda inicjująca. Ponadto sprawi, że instrukcja @synthesize będzie bardziej zwięzła.
Edycja: Dzięki najnowszej funkcji kompilatora automatycznej syntezy używam teraz podkreślenia dla ivar (w rzadkich przypadkach, gdy potrzebuję użyć ivar, aby dopasować to, co robi automatyczna synteza.
źródło
To tak naprawdę nic nie znaczy, to po prostu konwencja, której niektórzy ludzie używają do rozróżniania zmiennych składowych od zmiennych lokalnych.
Jeśli chodzi o błąd, to wygląda na to, że misja ma zły typ. Jaka jest jego deklaracja?
źródło
Dotyczy to tylko konwencji nazewnictwa dotyczącej syntetyzowania właściwości.
Kiedy zsyntetyzujesz zmienne w pliku .m, Xcode automatycznie dostarczy Ci inteligencję _variable.
źródło
Podkreślenie nie tylko umożliwia rozwiązywanie problemów z ivars bez uciekania się do używania self.member składni ale sprawia, że twój kod jest bardziej czytelny, ponieważ wiesz, kiedy zmienna jest ivar (ze względu na jej przedrostek podkreślenia) lub argument składowy (bez podkreślenia ).
Przykład:
źródło
self.image
, który uzyskuje dostęp do właściwości. Jedyny przypadek, w którym należy uzyskać dostęp do zmiennej instancji,_image
jest bezpośrednio winit
metodach idealloc
metodzie, wywołanie dowolnej innej metody może być ryzykowne (ponieważ obiekt jest w połowie zainicjowany lub zwolniony w połowie).Wydaje się, że jest to element „nadrzędny” w przypadku pytań dotyczących self.variableName i _variablename. To, co rzuciło mnie na pętlę, to to, że w .h miałem:
Prowadzi to do tego, że self.variableName i _variableName są dwiema różnymi zmiennymi w .m. Potrzebowałem:
Następnie w klasie „.m” self.variableName i _variableName są równoważne.
Nadal nie jestem pewien, dlaczego wiele przykładów wciąż działa, nawet jeśli tak się nie dzieje.
Promień
źródło
zamiast podkreślenia możesz użyć nazwy zmiennej self lub możesz zsyntetyzować zmienną, aby użyć zmiennej lub wyjścia bez podkreślenia.
źródło
W innych odpowiedziach brakuje tego, że używanie
_variable
zapobiega nieumyślnemu pisaniuvariable
i uzyskiwaniu dostępu do ivar, a nie (przypuszczalnie zamierzonej) właściwości.Kompilator zmusi cię do użycia albo
self.variable
lub_variable
. Stosowanie podkreśleń uniemożliwia wpisywanievariable
, co zmniejsza liczbę błędów programisty.źródło