Czy istnieje różnica między „zmienną instancji” a „właściwością” w Objective-c?
Nie jestem tego pewien. Myślę, że „właściwość” to zmienna instancji, która ma metody dostępu, ale mogę pomyśleć źle.
źródło
Czy istnieje różnica między „zmienną instancji” a „właściwością” w Objective-c?
Nie jestem tego pewien. Myślę, że „właściwość” to zmienna instancji, która ma metody dostępu, ale mogę pomyśleć źle.
Właściwość jest pojęciem bardziej abstrakcyjnym. Zmienna instancji jest dosłownie tylko miejscem do przechowywania, podobnie jak gniazdo w strukturze. Zwykle inne obiekty nigdy nie mają do nich bezpośredniego dostępu. Z drugiej strony właściwość to atrybut obiektu, do którego można uzyskać dostęp (brzmi niejasno i powinien). Zwykle właściwość zwraca lub ustawia zmienną instancji, ale może używać danych z kilku lub wcale. Na przykład:
@interface Person : NSObject {
NSString *name;
}
@property(copy) NSString *name;
@property(copy) NSString *firstName;
@property(copy) NSString *lastName;
@end
@implementation Person
@synthesize name;
- (NSString *)firstName {
[[name componentsSeparatedByString:@" "] objectAtIndex:0];
}
- (NSString *)lastName {
[[name componentsSeparatedByString:@" "] lastObject];
}
- (NSString *)setFirstName:(NSString *)newName {
NSArray *nameArray = [name componentsSeparatedByString:@" "];
NSArray *newNameArray [[NSArray arrayWithObjects:newName, nil] arrayByAddingObjectsFromArray:[nameArray subarrayWithRange:NSMakeRange(1, [nameArray size]-1)]];
self.name = [newNameArray componentsJoinedByString:@" "];
}
- (NSString *)setLastName:(NSString *)newName {
NSArray *nameArray = [name componentsSeparatedByString:@" "];
NSArray *newNameArray [[nameArray subarrayWithRange:NSMakeRange(0, [nameArray size]-2)] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:newName, nil]];
self.name = [newNameArray componentsJoinedByString:@" "];
}
@end
(Uwaga: powyższy kod jest błędny, ponieważ zakłada, że nazwa już istnieje i ma co najmniej dwa składniki (np. „Bill Gates” zamiast tylko „Gates”). Czułem, że poprawienie tych założeń uczyniłoby rzeczywisty punkt kodu mniej jasne, więc po prostu wskazuję to tutaj, aby nikt niewinnie nie powtórzył tych błędów.)
Właściwość jest przyjaznym sposobem implementacji metody pobierającej / ustawiającej dla jakiejś wartości, z dodatkowymi użytecznymi funkcjami i składnią. Właściwość może być obsługiwana przez zmienną instancji, ale możesz także zdefiniować metodę pobierającą / ustawiającą, aby wykonywała coś bardziej dynamicznego, np. Możesz zdefiniować właściwość lowerCase w ciągu, który dynamicznie tworzy wynik zamiast zwracać wartość jakiegoś elementu zmienna.
Oto przykład:
// === In your .h === @interface MyObject { NSString *propertyName; } // ... @property (nonatomic, retain) NSString *propertyName; // === In your .m @implementation === @synthesize propertyName /* = otherVarName */;
@property
Linia definiuje właściwość o nazwiepropertyName
typuNSString *
. Można to pobrać / ustawić przy użyciu następującej składni:myObject.propertyName = @"Hello World!"; NSLog("Value: %@", myObject.propertyName);
Kiedy przypisujesz lub czytasz
myObject.propertyName
, tak naprawdę wywołujesz metody ustawiające / pobierające na obiekcie.@synthesize
Linia informuje kompilator do generowania tych getter / ustawiające dla ciebie, stosując zmienną składową o tej samej nazwie obiektu do przechowywania wartości (lubotherVarName
jeśli używasz składni w komentarzach).Wraz z
@synthesize
możesz nadal przesłonić jeden z getter / setters, definiując swój własny. Konwencja nazewnictwa tych metod dotyczy metodysetPropertyName:
ustawiającej ipropertyName
(lubgetPropertyName
nie jest standardowa) metody pobierającej. Drugi będzie nadal generowany dla Ciebie.W swoim
@property
wierszu możesz zdefiniować wiele atrybutów w parenach dla właściwości, które mogą zautomatyzować takie rzeczy, jak bezpieczeństwo wątków i zarządzanie pamięcią. Domyślnie właściwość jest niepodzielna, co oznacza, że kompilator będzie opakował@synthesiz
wywołania get / set odpowiednimi blokadami, aby zapobiec problemom ze współbieżnością. Możesz określićnonatomic
atrybut, aby to wyłączyć (na przykład na iPhonie, dla którego chcesz domyślnie ustawić większość właściwościnonatomic
).Istnieją 3 wartości atrybutów, które sterują zarządzaniem pamięcią dla dowolnych
@synthesized
ustawiaczy. Pierwsza to,retain
która automatycznie wyślerelease
do starych wartości właściwości iretain
do nowych wartości. To jest bardzo przydatne.Drugi polega na
copy
tym, że utworzy kopię wszelkich przekazanych wartości, zamiast je zachować. Jest to dobra praktyka wcopy
przypadku NSString, ponieważ wywołujący może przekazać NSMutableString i zmienić go spod ciebie.copy
utworzy nową kopię wejścia, do którego tylko Ty masz dostęp.Trzeci polega
assign
na przypisaniu prostego wskaźnika bez wywoływania funkcji retain / release na starym lub nowym obiekcie.Na koniec możesz również użyć
readonly
atrybutu, aby wyłączyć metodę ustawiającą dla właściwości.źródło
Używam właściwości dla części interfejsu - gdzie obiekt łączy się z innymi obiektami, a zmienne instancji to rzeczy, których potrzebujesz w swojej klasie - nikt oprócz ciebie nie powinien ich widzieć i manipulować nimi.
źródło
Domyślnie właściwość readwrite będzie obsługiwana przez zmienną instancji, która ponownie zostanie automatycznie zsyntetyzowana przez kompilator.
Zmienna instancji to zmienna, która istnieje i zachowuje swoją wartość przez cały okres istnienia obiektu. Pamięć używana dla zmiennych instancji jest alokowana, gdy obiekt jest tworzony po raz pierwszy (poprzez alokację) i zwalniana, gdy obiekt jest zwalniany.
O ile nie określono inaczej, zsyntetyzowana zmienna instancji ma taką samą nazwę jak właściwość, ale z przedrostkiem podkreślenia. Na przykład w przypadku właściwości o nazwie firstName zsyntetyzowana zmienna instancji będzie miała nazwę _firstName.
źródło
Wcześniej ludzie używali nieruchomości publicznie, a ivars do użytku prywatnego, ale od kilku lat można również definiować nieruchomości w programie,
@implementation
aby używać ich prywatnie. Ale nadal używałbym ivars, jeśli to możliwe, ponieważ jest mniej liter do wpisania i zgodnie z tym artykułem działa szybciej . Ma to sens, ponieważ właściwości mają być „ciężkie”: przypuszcza się, że dostęp do nich można uzyskać z wygenerowanych metod pobierających / ustawiających lub zapisanych ręcznie.Jednak w ostatnich kodach Apple, ivary nie są już używane. Chyba dlatego, że jest bardziej
objc
niżC/C++
plus łatwiej korzystać z właściwościassign
,nullable
itpźródło
@implementation
chce wykazać podobieństwa do Swift. Nadal wolę również zmienne zapasowe, aby nie marnować wywołania funkcji wirtualnej w celu wyszukania prostego pola mojej własnej klasy (a dzieje się tak, gdy uzyskuje się dostęp do właściwości).