Jaka jest różnica między Ivars a właściwościami w Objective-C
Jaka jest semantyczna różnica między tymi 3 sposobami używania ivarów a właściwościami w objective-c?
1.
@class MyOtherObject;
@interface MyObject {
}
@property (nonatomic, retain) MyOtherObject *otherObj;
2.
#import "MyOtherObject.h"
@interface MyObject {
MyOtherObject *otherObj;
}
@property (nonatomic, retain) MyOtherObject *otherObj;
3.
#import "MyOtherObject.h"
@interface MyObject {
MyOtherObject *otherObj;
}
2 answers
Liczba 1 różni się od dwóch pozostałych tym, że forward deklaruje klasę MyOtherObject, aby zminimalizować ilość kodu widzianego przez kompilator i linker, a także potencjalnie uniknąć odniesień okrągłych. Jeśli zrobisz to w ten sposób pamiętaj, aby umieścić # import do .plik M.
Deklarując właściwość@, (i dopasowując @synthesize wm) plik, automatycznie generujesz metody accessora z semantyką pamięci obsługiwaną w sposób określony przez Ciebie. Regułą dla większości obiektów jest zachowanie, ale NSStrings, na przykład powinien używać Copy. Natomiast Singletoni i delegaci powinni zwykle używać przypisania. Akcesoria do pisania ręcznego są żmudne i podatne na błędy, więc oszczędza to wiele pisania i głupich błędów.
Również deklaracja właściwości syntetyzowanej pozwala wywołać metodę accessor używając notacji kropkowej w następujący sposób:
self.otherObj = someOtherNewObject; // set it
MyOtherObject *thingee = self.otherObj; // get it
Zamiast normalnego, przekazującego wiadomość sposobu:
[self setOtherObject:someOtherNewObject]; // set it
MyOtherObject *thingee = [self otherObj]; // get it
Za kulisami naprawdę wywołujesz metodę, która wygląda tak:
- (void) setOtherObj:(MyOtherObject *)anOtherObject {
if (otherObject == anOtherObject) {
return;
}
MyOtherObject *oldOtherObject = otherObject; // keep a reference to the old value for a second
otherObject = [anOtherObject retain]; // put the new value in
[oldOtherObject release]; // let go of the old object
} // set it
...lub to
- (MyOtherObject *) otherObject {
return otherObject;
} // get it
Totalny ból w tyłku. Teraz zrób to dla każdego Ivara w klasie. Jeśli nie zrobisz tego dokładnie dobrze, dostaniesz wyciek pamięci. Najlepiej pozwolić kompilatorowi wykonać pracę.
Widzę, że Numer 1 nie ma Ivara. Zakładając, że to nie jest literówka, jest w porządku, ponieważ dyrektywy @ property / @synthesize będą również deklarować ivar dla Ciebie, za kulisami. uważam, że jest to nowość dla Mac OS X-Snow Leopard i iOS4.
Numer 3 nie ma tych accesorów, więc musisz je napisać sam. Jeśli chcesz, aby metody accessora miały skutki uboczne, wykonaj standardowy taniec zarządzania pamięcią, jak pokazano powyżej, a następnie wykonaj dowolną pracę poboczną, której potrzebujesz, wewnątrz metody accessora. Jeśli zsyntetyzujesz właściwość oraz piszesz własną , to Twoja wersja ma priorytet.
Czy wszystko pokryłem?Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-25 06:43:31
W dawnych czasach miałeś Ivary, a jeśli chcesz pozwolić innym klasom ustawić lub przeczytać je, musisz zdefiniować getter (tj. -(NSString *)foo)
i setter(tj. -(void)setFoo:(NSString *)aFoo;
).
Jakie właściwości daje Ci setter i getter za darmo (prawie!) wraz z Ivarem. Więc kiedy definiujesz właściwość teraz, możesz ustawić atomiczność (czy chcesz zezwolić na wiele akcji ustawień z wielu wątków, na przykład), a także przypisać/zachować / skopiować semantykę (to znaczy, jeśli setter skopiuje nowa wartość lub po prostu zapisz bieżącą wartość-ważne, jeśli inna klasa próbuje ustawić właściwość string z mutable string, który może zostać zmieniony później).
To właśnie robi @synthesize
. Wiele osób pozostawia nazwę ivar tak samo, ale można ją zmienić, pisząc oświadczenie synthesize (np. @synthesize foo=_foo;
oznacza utworzenie Ivara o nazwie _foo
dla właściwości foo
, więc jeśli chcesz przeczytać lub napisać tę właściwość i nie używasz self.foo
, będziesz musiał użyć _foo = ...
- to po prostu pomaga Złap bezpośrednie odniesienia do ivar, jeśli chcesz tylko przejść przez setter i getter).
Począwszy od Xcode 4.6, nie musisz używać instrukcji @synthesize
- kompilator zrobi to automatycznie i domyślnie poprzedzi nazwę Ivara znakiem _
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-24 12:13:18