Zoeken…


Syntaxis

  • Type- ID @property ( optioneel_attributen, ... );
  • @synthesize identifier = optioneel_backing_ivar ;
  • @ dynamische identificatie ;

parameters

Attribuut Beschrijving
atomic Impliciete. Maakt synchronisatie mogelijk in gesynthetiseerde accessormethoden.
nonatomic Schakelt synchronisatie uit in de gesynthetiseerde accessormethoden.
readwrite Impliciete. Synthetiseert getter, setter en backing ivar.
readonly Synthetiseert alleen de getter-methode en achtergrond-ivar, die direct kunnen worden toegewezen.
getter= naam Specificeert de naam van de getter-methode, impliciet is propertyName .
setter= naam Specificeert de naam van de setter-methode, impliciteit is setPropertyName: Dubbelpunt : moet een deel van de naam zijn.
strong Impliciet voor objecten onder ARC . De backing ivar wordt gesynthetiseerd met __strong , waardoor deallocatie van het gerefereerde object wordt voorkomen.
retain Synoniem voor strong .
copy Hetzelfde als strong , maar de gesynthetiseerde setter roept ook -copy op de nieuwe waarde op.
unsafe_unretained Impliciet, behalve voor objecten onder ARC. De backing ivar wordt gesynthetiseerd met behulp van __unsafe_unretained , wat (voor obejcts) resulteert in een bengelende wijzer zodra het gerefereerde object dealloceert.
assign Synoniem voor unsafe_unretained . Geschikt voor niet-objecttypen.
weak Backing ivar wordt gesynthetiseerd met behulp van __weak , dus de waarde wordt tenietgedaan zodra het object waarnaar wordt verwezen, is toegewezen.
class Eigendomstoegangen worden gesynthetiseerd als klassemethoden in plaats van instantiemethoden. Er wordt geen achtergrondopslag gesynthetiseerd.
nullable De eigenschap accepteert nil . Hoofdzakelijk gebruikt voor snelle bruggen.
nonnull De eigenschap accepteert geen nil . Hoofdzakelijk gebruikt voor snelle bruggen.
null_resettable De eigenschap accepteert nil in setter, maar retourneert nooit nil van getter. Uw aangepaste implementatie van getter of setter moet dit gedrag waarborgen. Hoofdzakelijk gebruikt voor snelle bruggen.
null_unspecified Impliciete. De eigenschap geeft geen verwerking van nil . Hoofdzakelijk gebruikt voor snelle bruggen.

Wat zijn eigenschappen?

Hier is een voorbeeldklasse die een aantal instantievariabelen heeft, zonder eigenschappen te gebruiken:

@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

Dit is nogal wat boilerplate-code om een eenvoudige instantievariabele te maken. U moet de instantievariabele maken en toegangsmethoden maken die niets anders doen dan de instantievariabele instellen of retourneren. Dus met Objective-C 2.0 introduceerde Apple eigenschappen die automatisch een deel van of alle boilerplate-code genereren.

Hier is de bovenstaande klasse herschreven met eigenschappen:

@interface TestClass

@property NSString *someString;
@property int someInt;

@end


@implementation testClass

@end

Een eigenschap is een instantievariabele gekoppeld met automatisch gegenereerde getters en setters. Voor een eigenschap met de naam someString , worden de getter en de setter respectievelijk someString en setSomeString: De naam van de instantievariabele is standaard de naam van de eigenschap voorafgegaan door een onderstrepingsteken (dus de instantievariabele voor someString wordt _someString , maar dit kan worden genegeerd met een @synthesize instructie in de sectie @implementation :

@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

Eigenschappen kunnen worden geopend door de getters en setters te bellen:

[testObject setSomeString:@"Foo"];
NSLog(@"someInt is %d", [testObject someInt]);

Ze kunnen ook worden geopend met behulp van puntnotatie:

testObject.someString = @"Foo";
NSLog(@"someInt is %d", testObject.someInt);

Aangepaste getters en setters

De standaard eigenschap getters en setters kunnen worden opgeheven:

@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

Dit kan handig zijn om bijvoorbeeld luie initialisatie te bieden (door de getter te negeren om de beginwaarde in te stellen als deze nog niet is ingesteld):

- (NSString *)someString {
    if (_someString == nil) {
        _someString = [self getInitialValueForSomeString];
    }
    return _someString;
}

U kunt ook een eigenschap maken die de waarde ervan in de getter berekent:

@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

Eigenschappen die updates veroorzaken

Dit object, Shape heeft een eigenschap image die afhankelijk is van numberOfSides en sideWidth . Als een van beide is ingesteld, moet de image opnieuw worden berekend. Maar herberekening is vermoedelijk lang en hoeft slechts eenmaal te worden uitgevoerd als beide eigenschappen zijn ingesteld, dus de Shape biedt een manier om beide eigenschappen in te stellen en slechts eenmaal opnieuw te berekenen. Dit wordt gedaan door de eigenschap ivars rechtstreeks in te stellen.

In vorm. 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

In 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

Wanneer eigenschappen worden toegewezen aan (met object.property = value ), wordt de setter-methode setProperty: aangeroepen. Deze setter, zelfs indien geleverd door @synthesize , kan worden opgeheven, zoals in dit geval voor numberOfSides en sideWidth . Als u echter de eigenschap ivar van een eigenschap rechtstreeks instelt (via property als het object self is, of object->property ), wordt de getter of setter niet aangeroepen, zodat u dingen kunt doen zoals meerdere eigenschappensets die slechts één update oproepen of bypass-bijwerkingen veroorzaakt door de setter.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow