Numer 1 różni się od pozostałych dwóch deklaracją do przodu klasy MyOtherObject, aby zminimalizować ilość kodu widzianego przez kompilator i konsolidator, a także potencjalnie uniknąć cyklicznych odwołań. Jeśli robisz to w ten sposób, pamiętaj o umieszczeniu #import w pliku .m.
Deklarując @właściwość (i dopasowując @synthesize w pliku .m), automatycznie generujesz metody akcesorów z semantyką pamięci obsługiwaną w określony sposób. Podstawową zasadą dla większości obiektów jest Zachowaj, ale NSStrings, na przykład, powinno używać Kopiuj. Natomiast Singletons i Delegates zwykle powinni używać Assign. Akcesory do ręcznego pisania są żmudne i podatne na błędy, więc oszczędza to wiele błędów związanych z pisaniem i głupimi błędami.
Ponadto zadeklarowanie zsyntetyzowanej właściwości umożliwia wywołanie metody akcesora przy użyciu notacji kropkowej w następujący sposób:
self.otherObj = someOtherNewObject;
MyOtherObject *thingee = self.otherObj;
Zamiast normalnego sposobu przekazywania wiadomości:
[self setOtherObject:someOtherNewObject];
MyOtherObject *thingee = [self otherObj];
Za kulisami naprawdę wywołujesz metodę, która wygląda następująco:
- (void) setOtherObj:(MyOtherObject *)anOtherObject {
if (otherObject == anOtherObject) {
return;
}
MyOtherObject *oldOtherObject = otherObject;
otherObject = [anOtherObject retain];
[oldOtherObject release];
}
…albo to
- (MyOtherObject *) otherObject {
return otherObject;
}
Całkowity ból w tyłku, prawda. Teraz zrób to dla każdego ivara w klasie. Jeśli nie zrobisz tego dokładnie dobrze, pojawi się wyciek pamięci. Najlepiej po prostu pozwolić kompilatorowi wykonać pracę.
Widzę, że numer 1 nie ma ivar. Zakładając, że to nie jest literówka, jest w porządku, ponieważ dyrektywy @property / @synthesize zadeklarują również ivar za kulisami. Uważam, że to nowość w systemie Mac OS X - Snow Leopard i iOS4.
Numer 3 nie ma wygenerowanych akcesorów, więc musisz je napisać samodzielnie. Jeśli chcesz, aby metody akcesorów miały efekty uboczne, wykonaj standardowy taniec zarządzania pamięcią, jak pokazano powyżej, a następnie wykonaj dowolną pracę poboczną w ramach metody akcesora. Jeśli syntetyzować nieruchomości , jak również pisać własne , a następnie swoją wersja posiada priorytet.
Czy omówiłem wszystko?
setFoo:
Ifoo
), możesz używać notacji kropkowej.W dawnych czasach miałeś bluszcze i jeśli chciałeś pozwolić innej klasie ustawić je lub przeczytać, to musiałeś zdefiniować metodę pobierającą (tj.
-(NSString *)foo)
I ustawiającą (tj-(void)setFoo:(NSString *)aFoo;
.).To, co daje ci właściwości, to seter i getter za darmo (prawie!) Wraz z ivar. Więc kiedy teraz definiujesz właściwość, możesz ustawić atomowość (na przykład czy chcesz zezwolić na wiele działań ustawień z wielu wątków), a także przypisać / zachować / skopiować semantykę (to znaczy, czy ustawiający powinien skopiować nową wartość lub po prostu zapisz bieżącą wartość - ważne, jeśli inna klasa próbuje ustawić twoją właściwość string za pomocą mutowalnego ciągu, który może zostać zmieniony później).
To właśnie
@synthesize
robi. Wiele osób pozostawia tę samą nazwę ivar, ale możesz ją zmienić podczas pisania instrukcji synthesize (tj.@synthesize foo=_foo;
Oznacza utworzenie ivar o nazwie_foo
dla właściwościfoo
, więc jeśli chcesz czytać lub pisać tę właściwość, a nie używaszself.foo
, trzeba użyć_foo = ...
- po prostu pomaga złapać bezpośrednie odniesienia do ivar, jeśli chcesz przejść tylko przez setter i getter).Od Xcode 4.6 nie musisz używać
@synthesize
instrukcji - kompilator zrobi to automatycznie i domyślnie doda nazwę ivar do nazwy ivar_
.źródło