Czy zadeklarowane właściwości wymagają odpowiedniej zmiennej instancji?

Czy właściwości w Objective-C 2.0 wymagają zadeklarowania odpowiedniej zmiennej instancji? Na przykład, jestem przyzwyczajony do robienia czegoś takiego:

MyObject.h

@interface MyObject : NSObject {
NSString *name;
}
@property (nonatomic, retain) NSString *name;
@end

MyObject.m

@implementation
@synthesize name;
@end

Jednak, co by było, gdybym zrobił to zamiast tego:

MyObject.h

@interface MyObject : NSObject {
}
@property (nonatomic, retain) NSString *name;
@end
Czy to jest nadal ważne? I czy w jakiś sposób różni się od mojego poprzedniego przykładu?
Author: Josh Caswell, 2010-06-19

6 answers

Jeśli używasz nowoczesnego środowiska uruchomieniowego Objective-C (jest to albo iOS 3.x lub większe, lub 64-bitowe Snow Leopard lub większe) wtedy nienie trzeba zdefiniować ivars dla swoich właściwości w takich przypadkach.

Kiedy @synthesize własność, ivar będzie w efekcie zsyntetyzowany również dla Ciebie. To się wokół scenariusza "fragile-ivar". Więcej o tym można przeczytać na kakao z miłością

 94
Author: jbrennan,
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
2010-06-19 04:26:31

W interfejsie można formalnie zadeklarować zmienną instancji pomiędzy klamrami, lub poprzez @property poza klamrami, lub oba. Tak czy inaczej, stają się atrybutami klasy. Różnica polega na tym, że jeśli zadeklarujesz @property, możesz zaimplementować używając @synthesize, który automatycznie koduje Twój getter / setter. Auto-koder setter inicjalizuje liczby całkowite i unosi się do zera, na przykład. Jeśli zadeklarujesz zmienną instancji i nie podasz odpowiadającej jej @property, nie możesz użyć @synthesize i musi napisać własny getter / setter.

Możesz zawsze nadpisać kodowany automatycznie getter/setter, podając swój własny. Zwykle robi się to z właściwością managedObjectContext, która jest leniwie ładowana. W ten sposób deklarujesz swoją managedObjectContext jako właściwość, ale także piszesz metodę -(NSManagedObjectContext *)managedObjectContext. Przypomnijmy, że metoda, która ma taką samą nazwę jak zmienna/właściwość instancji, jest metodą "getter".

Metoda deklaracji @property umożliwia również inne opcje, takie jak retain i readonly, które metoda deklaracji zmiennej instancji nie. Zasadniczo, ivar jest stary sposób, i @property rozszerza go i czyni go bardziej fantazyjne/łatwiejsze. Możesz odnosić się do obu używając jaźni. prefiks, czy nie, nie ma znaczenia, o ile nazwa jest unikalna dla tej klasy. W przeciwnym razie, jeśli twoja superclass ma taką samą nazwę nieruchomości, jak ty, musisz powiedzieć albo jak self.name lub super.name w celu określenia, o której nazwie mówisz.

W ten sposób zobaczysz coraz mniej ludzi deklaruje ivar s pomiędzy klamrami, a zamiast tego przesuwa się w kierunku podania @property, a następnie wykonuje @synthesize. Nie można wykonać @synthesize w swojej implementacji bez odpowiedniego @property. Syntezator wie tylko, jaki jest typ atrybutu ze specyfikacji @property. Instrukcja synthesize pozwala również na zmianę nazwy właściwości, dzięki czemu można odwoływać się do właściwości za pomocą jednej nazwy (skrótu) w kodzie, ale poza nim w.plik H używa pełnej nazwy. Jednak z naprawdę fajnym autouzupełnianiem że XCode ma teraz, jest to mniej korzyści, ale nadal istnieje.

Mam nadzieję, że to pomoże wyjaśnić całe zamieszanie i dezinformację, które krążą wokół.

 69
Author: PapaSmurf,
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-07-09 06:07:55

Działa w obie strony, ale jeśli nie zadeklarujesz ich w nawiasach klamrowych, nie zobaczysz ich wartości w debuggerze w xcode.

 8
Author: rickm,
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
2011-04-13 03:04:18

Z Dokumentacji:

Ogólnie zachowanie właściwości jest identyczne zarówno w nowoczesnych, jak i starszych środowiskach wykonawczych (patrz "wersje uruchomieniowe i platformy" w Objective-C Runtime Programming Guide). Jest jedna zasadnicza różnica: nowoczesny runtime obsługuje syntezę zmiennych instancji, podczas gdy starszy runtime nie.

Aby @synthesize działał w legacy runtime, musisz podać zmienną instancyjną o tej samej nazwie i zgodnym typie Właściwości lub określa inną istniejącą zmienną instancji w instrukcji @ synthesize. W nowoczesnym środowisku uruchomieniowym, jeśli nie podasz zmiennej instancji, kompilator doda ją za Ciebie.

 3
Author: Charlie Elliott,
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
2011-03-28 06:07:33

Jeśli używasz XCode 4.4 lub nowszego, wygeneruje to zmienną instancji syntetyzującą kod dla Ciebie.

Musisz tylko zadeklarować właściwości jak poniżej; wygeneruje to kod syntezujący i zmienną instancji deklarującą kod dla Ciebie.

@property (nonatomic, strong) NSString *name;

Wygeneruje kod syntezujący jako

@synthesize name = _name;

I możesz uzyskać dostęp do zmiennej instancji za pomocą _name jest to podobne do declare

NSString* _name

Ale jeśli zadeklarujesz właściwość tylko do odczytu to tak jak

@property (nonatomic, strong, readonly) NSString *name;

Wygeneruje kod

@synthesize name;

Lub

@synthesize name = name; 

Więc powinieneś uzyskać dostęp do natychmiastowej nazwy zmiennej bez prefiksu "_" w dowolny sposób możesz napisać własny kod syntezujący, a kompilator wygeneruje kod dla Ciebie. możesz napisać

@synthesize name = _name;
 3
Author: Shafraz Buhary,
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-10-30 17:46:24

Język Programowania Objective-C: Property Implementation Directives

Istnieją różnice w zachowaniu syntezy accesora, które zależą od runtime (patrz także "różnica Runtime"):

  • Dla starszych czasów uruchamiania zmienne instancji muszą być już zadeklarowane w bloku @ interface bieżącej klasy. Jeśli istnieje zmienna instancyjna o tej samej nazwie co właściwość, a jej typ jest zgodny z typem właściwości, to used-w przeciwnym razie pojawia się błąd kompilatora.

  • W przypadku nowoczesnych środowisk uruchomieniowych (patrz" wersje uruchomieniowe i platformy " w podręczniku programowania uruchomieniowego Objective-C) zmienne instancji są syntetyzowane w razie potrzeby. Jeśli zmienna instancyjna o tej samej nazwie już istnieje, jest używana.

 1
Author: Nate,
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
2012-01-11 06:13:20