Sök…


Syntax

  • @property (optional_attributes, ...) Typ identifierare;
  • @synthesize identifier = option_backing_ivar ;
  • @dynamisk identifierare ;

parametrar

Attribut Beskrivning
atomic Implicit. Aktiverar synkronisering i syntetiserade accessormetoder.
nonatomic Inaktiverar synkronisering i de syntetiserade accessormetoderna.
readwrite Implicit. Syntetiserar getter, setter och backning ivar.
readonly Syntetiserar endast getter-metoden och ivar som backas, som kan tilldelas direkt.
getter= namn Anger namnet på getter-metoden, implicit är propertyName .
setter= namn Anger namnet på setter-metoden, implicit är setPropertyName: Kolon : måste vara en del av namnet.
strong Implicit för objekt under ARC . Den __strong syntetiseras med hjälp av __strong , vilket förhindrar omlokalisering av refererat objekt.
retain Synonym för strong .
copy Samma som strong , men den syntetiserade setteren kallar också -copy på det nya värdet.
unsafe_unretained Implicit, med undantag för objekt under ARC. Den stödjande ivaren syntetiseras med hjälp av __unsafe_unretained , vilket (för objekter) resulterar i dinglande pekare när det refererade objektet har omlokaliserats.
assign Synonym för unsafe_unretained . Lämplig för andra typer än objekt.
weak Säkerhetskopiering av ivar syntetiseras med __weak , så värdet kommer att upphöra när det refererade objektet har omlokaliserats.
class Fastighetstillträdare syntetiseras som klassmetoder istället för instansmetoder. Ingen stödlagring är syntetiserad.
nullable Egenskapen accepterar nil . Används främst för snabb överbryggning.
nonnull Egenskapen accepterar inte nil . Används främst för snabb överbryggning.
null_resettable Egenskapen accepterar nil i setter, men returnerar aldrig nil från getter. Din anpassade implementering av getter eller setter måste säkerställa detta beteende. Används främst för snabb överbryggning.
null_unspecified Implicit. Egenskapen anger inte hantering av nil . Används främst för snabb överbryggning.

Vad är egenskaper?

Här är en exempelklass som har ett par instansvariabler utan att använda egenskaper:

@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

Det här är en hel del pannplåtkod för att skapa en enkel instansvariabel. Du måste skapa instansvariabeln och skapa åtkomstmetoder som inte gör något annat än att ställa in eller returnera instansvariabeln. Så med Objekt-C 2.0 introducerade Apple egenskaper som automatiskt genererar en del av eller hela källan för pannan.

Här är ovanstående klass omskrivna med egenskaper:

@interface TestClass

@property NSString *someString;
@property int someInt;

@end


@implementation testClass

@end

En egenskap är en instansvariabel parad med auto-genererade getters och setters. För en egenskap som heter someString kallas getter och setter someString respektive setSomeString: Namnet på instansvariabeln är som standard namnet på egenskapen förinställd med en understreck (så instansvariabeln för someString kallas _someString , men det kan åsidosättas med ett @synthesize direktiv i avsnittet @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

Egenskaper kan nås genom att ringa Getters och Seters:

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

De kan också nås med punktnotation:

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

Anpassade bokstäver och uppsättare

Standardegenskaperna och -inställningarna kan åsidosättas:

@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

Detta kan vara användbart för att till exempel ge lat initiering (genom att åsidosätta gettern för att ställa in initialvärdet om det ännu inte har ställts in):

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

Du kan också skapa en egenskap som beräknar dess värde i getter:

@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

Egenskaper som orsakar uppdateringar

Detta objekt, Shape har en egenskap image som beror på numberOfSides och sideWidth . Om någon av dem är inställd måste image beräknas om. Men omberäkningen är förmodligen lång och behöver bara göras en gång om båda egenskaperna är inställda, så Shape ger ett sätt att ställa in båda egenskaperna och bara beräkna en gång. Detta görs genom att ställa in fastigheten ivars direkt.

I 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

I 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

När egenskaper tilldelas (med hjälp av object.property = value ) setProperty: Denna inställare, även om den tillhandahålls av @synthesize , kan åsidosättas, som den är i detta fall för numberOfSides och sideWidth . Men om du ställer in en ivars ivar direkt (genom property om objektet är själv, eller object->property ), ringer det inte getter eller setter, vilket gör att du kan göra saker som flera egendomsuppsättningar som bara kallar en uppdatering eller bypass biverkningar orsakade av setteren.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow