Objective-C Language
Nieruchomości
Szukaj…
Składnia
- @property ( opcjonalny_atrybuty, ... ) identyfikator typu ;
- @synthesize identifier = opcjonalny_powrót_powrót ;
- @dynamiczny identyfikator ;
Parametry
Atrybut | Opis |
---|---|
atomic | Domniemany. Umożliwia synchronizację w zsyntetyzowanych metodach akcesorów. |
nonatomic | Wyłącza synchronizację w metodach zsyntetyzowanego akcesorium. |
readwrite | Domniemany. Syntezuje getter, seter i backing ivar. |
readonly | Syntetyzuje tylko metodę gettera i backing ivar, które można przypisać bezpośrednio. |
getter= nazwa | Określa nazwę metody pobierającej, domyślnie jest propertyName . |
setter= nazwa | Określa nazwę metody ustawiającej, implikacja to setPropertyName: Dwukropek : musi być częścią nazwy. |
strong | Domniemane dla obiektów objętych ARC . __strong jest syntetyzowany przy użyciu __strong , co zapobiega dealokacji obiektu, do którego __strong odwołanie. |
retain | Synonim strong . |
copy | Taki sam jak strong , ale -copy syntezator wywołuje także -copy dla nowej wartości. |
unsafe_unretained | Domniemane, z wyjątkiem obiektów objętych ARC. Podstawowy ivar jest syntetyzowany przy użyciu __unsafe_unretained , co (dla obejcts) powoduje zwisający wskaźnik po zwolnieniu obiektu, do którego się odwołuje. |
assign | Synonim dla unsafe_unretained . Odpowiedni dla typów niebędących obiektami. |
weak | Tworzenie kopii __weak jest syntetyzowane za pomocą __weak , więc wartość zostanie anulowana, gdy __weak obiekt zostanie zwolniony. |
class | Akcesoria do właściwości są syntetyzowane jako metody klasowe zamiast metod instancji. Żadne miejsce do przechowywania kopii zapasowej nie jest syntetyzowane. |
nullable | Właściwość przyjmuje wartości nil . Używany głównie do szybkiego mostkowania. |
nonnull | Właściwość nie przyjmuje wartości nil . Używany głównie do szybkiego mostkowania. |
null_resettable | Właściwość akceptuje wartości nil w seterze, ale nigdy nie zwraca wartości nil z gettera. Twoja niestandardowa implementacja gettera lub settera musi zapewnić takie zachowanie. Używany głównie do szybkiego mostkowania. |
null_unspecified | Domniemany. Ta właściwość nie określa obsługi wartości nil . Używany głównie do szybkiego mostkowania. |
Jakie są właściwości?
Oto przykładowa klasa, która ma kilka zmiennych instancji, bez użycia właściwości:
@interface TestClass : NSObject {
NSString *_someString;
int _someInt;
}
-(NSString *)someString;
-(void)setSomeString:(NSString *)newString;
-(int)someInt;
-(void)setSomeInt:(NSString *)newInt;
@end
@implementation TestClass
-(NSString *)someString {
return _someString;
}
-(void)setSomeString:(NSString *)newString {
_someString = newString;
}
-(int)someInt {
return _someInt;
}
-(void)setSomeInt:(int)newInt {
_someInt = newInt;
}
@end
Jest to całkiem sporo kodu typu „płyta podstawowa” do utworzenia prostej zmiennej instancji. Musisz utworzyć zmienną instancji i stworzyć metody akcesora, które nie robią nic poza ustawieniem lub zwróceniem zmiennej instancji. Tak więc w Objective-C 2.0, Apple wprowadził właściwości, które automatycznie generują część lub całość kodu tablicy kontrolnej.
Oto powyższa klasa przepisana właściwościami:
@interface TestClass
@property NSString *someString;
@property int someInt;
@end
@implementation testClass
@end
Właściwość jest zmienną instancji połączoną z automatycznie generowanymi obiektami pobierającymi i ustawiającymi. Dla właściwość o nazwie someString
, getter i setter nazywane są someString
i setSomeString:
odpowiednio. Nazwa zmiennej instancji jest domyślnie nazwa własności poprzedzona znakiem podkreślenia (tak zmienna instancji dla someString
nazywa _someString
, ale może to być pominięte z @synthesize
dyrektywy w @implementation
sekcji:
@synthesize someString=foo; //names the instance variable "foo"
@synthesize someString; //names it "someString"
@synthesize someString=_someString; //names it "_someString"; the default if
//there is no @synthesize directive
Dostęp do właściwości można uzyskać, wywołując metody pobierające i ustawiające:
[testObject setSomeString:@"Foo"];
NSLog(@"someInt is %d", [testObject someInt]);
Można również uzyskać do nich dostęp za pomocą notacji kropkowej:
testObject.someString = @"Foo";
NSLog(@"someInt is %d", testObject.someInt);
Niestandardowe pobieracze i ustawiacze
Domyślne moduły pobierające i ustawiające właściwości można zastąpić:
@interface TestClass
@property NSString *someString;
@end
@implementation TestClass
// override the setter to print a message
- (void)setSomeString:(NSString *)newString {
NSLog(@"Setting someString to %@", newString);
// Make sure to access the ivar (default is the property name with a _
// at the beginning) because calling self.someString would call the same
// method again leading to an infinite recursion
_someString = newString;
}
- (void)doSomething {
// The next line will call the setSomeString: method
self.someString = @"Test";
}
@end
Może to być przydatne do zapewnienia na przykład leniwej inicjalizacji (poprzez przesłonięcie modułu pobierającego, aby ustawić wartość początkową, jeśli jeszcze nie została ustawiona):
- (NSString *)someString {
if (_someString == nil) {
_someString = [self getInitialValueForSomeString];
}
return _someString;
}
Możesz także utworzyć właściwość, która oblicza jej wartość w module pobierającym:
@interface Circle : NSObject
@property CGPoint origin;
@property CGFloat radius;
@property (readonly) CGFloat area;
@end
@implementation Circle
- (CGFloat)area {
return M_PI * pow(self.radius, 2);
}
@end
Właściwości powodujące aktualizacje
Ten obiekt, Shape
ma właściwość image
, który zależy od numberOfSides
i sideWidth
. Jeśli którykolwiek z nich jest ustawiony, image
musi zostać ponownie obliczony. Ponowne obliczenie jest jednak prawdopodobnie długie i należy je wykonać tylko raz, jeśli obie właściwości są ustawione, więc Shape
zapewnia sposób ustawienia obu właściwości i ponownego obliczenia tylko raz. Odbywa się to poprzez bezpośrednie ustawienie właściwości ivars.
W Shape.h
@interface Shape {
NSUInteger numberOfSides;
CGFloat sideWidth;
UIImage * image;
}
// Initializer that takes initial values for the properties.
- (instancetype)initWithNumberOfSides:(NSUInteger)numberOfSides withWidth:(CGFloat)width;
// Method that allows to set both properties in once call.
// This is useful if setting these properties has expensive side-effects.
// Using a method to set both values at once allows you to have the side-
// effect executed only once.
- (void)setNumberOfSides:(NSUInteger)numberOfSides andWidth:(CGFloat)width;
// Properties using default attributes.
@property NSUInteger numberOfSides;
@property CGFloat sideWidth;
// Property using explicit attributes.
@property(strong, readonly) UIImage * image;
@end
W Shape.m
@implementation AnObject
// The variable name of a property that is auto-generated by the compiler
// defaults to being the property name prefixed with an underscore, for
// example "_propertyName". You can change this default variable name using
// the following statement:
// @synthesize propertyName = customVariableName;
- (id)initWithNumberOfSides:(NSUInteger)numberOfSides withWidth:(CGFloat)width {
if ((self = [self init])) {
[self setNumberOfSides:numberOfSides andWidth:width];
}
return self;
}
- (void)setNumberOfSides:(NSUInteger)numberOfSides {
_numberOfSides = numberOfSides;
[self updateImage];
}
- (void)setSideWidth:(CGFloat)sideWidth {
_sideWidth = sideWidth;
[self updateImage];
}
- (void)setNumberOfSides:(NSUInteger)numberOfSides andWidth:(CGFloat)sideWidth {
_numberOfSides = numberOfSides;
_sideWidth = sideWidth;
[self updateImage];
}
// Method that does some post-processing once either of the properties has
// been updated.
- (void)updateImage {
...
}
@end
Gdy właściwości są przypisane do (przy użyciu object.property = value
), wywoływana jest metoda ustawiająca setProperty:
object.property = value
Ten seter, nawet jeśli został podany przez @synthesize
, może być zmieniona, jak to jest w tym przypadku dla numberOfSides
i sideWidth
. Jeśli jednak ustawisz ivar właściwości bezpośrednio (poprzez property
jeśli obiekt jest własny, lub object->property
), nie wywołuje on modułu pobierającego ani ustawiającego, umożliwiając wykonywanie rzeczy takich jak wiele zestawów właściwości, które wywołują tylko jedną aktualizację lub ominąć skutki uboczne wywoływane przez setera.