6 Stimmen

Objective-C Eigenschaft - Getter Verhalten

Was ist technisch falsch an folgendem:

@property(nonatomic, assign) NSUInteger timestamp;
@property(nonatomic, readonly, getter = timestamp) NSUInteger startTime;
@property(nonatomic, assign) NSUInteger endTime;

Ich bin mir sicher, dass ich eine bessere Möglichkeit finden kann, das zu organisieren, aber das ist, womit ich an einem Punkt in meinem Projekt gelandet bin und ich habe bemerkt, dass der Zugriff auf die startTime Eigenschaft immer 0 zurückgibt, auch wenn die timestamp Eigenschaft auf einen korrekten Zeitstempel gesetzt ist.

Es scheint, dass, nachdem ich den Getter von startTime auf eine existierende Eigenschaft (timestamp) gesetzt habe, der Wert von timestamp nicht weitergeleitet wird, wenn ich folgendes mache:

event.startTime => 0
event.timestamp => 1340920893

Übrigens sind das alles Zeitstempel.

Nur als Erinnerung, ich weiß, dass das oben in meinem Projekt passieren sollte, aber ich verstehe nicht, warum der Zugriff auf startTime nicht zur timestamp Eigenschaft weitergeleitet wird.

UPDATE

In meiner Implementation synthetisiere ich all diese Eigenschaften:

@synthesize timestamp, endTime, startTime;

Bitte überprüfen Sie ein Beispielobjekt, das dies auf meinem Gist auf GitHub zeigt: https://gist.github.com/3013951

8voto

zpasternack Punkte 17712

In Ihrer Beschreibungsmethode verwenden Sie nicht die Eigenschaft, sondern greifen auf das Ivar zu.

-(NSString*) description
{
    return [NSString stringWithFormat:@"Event< timestamp:%d, start:%d >", 
             timestamp, 
             startTime]; // <-- Hier greifen Sie auf die Instanzvariable zu und nicht auf die Eigenschaft.
}

Dies wird für Sie funktionieren:

-(NSString*) description
{
    return [NSString stringWithFormat:@"Event< timestamp:%d, start:%d >", 
             timestamp, 
             self.startTime]; // <-- Hier wird der Eigenschaftszugriff verwendet.
}

Das Property-vs-Ivar-Ding verwirrt immer wieder Leute, also entschuldigen Sie mich, während ich kurz darüber schwadroniere. :) Wenn Sie dies bereits wissen, überspringen Sie bitte diesen Abschnitt.

Wenn Sie eine Eigenschaft erstellen und synthezieren, wie Sie es oben getan haben, passieren zwei Dinge:

  1. Es wird ein Ivar vom richtigen Typ erstellt.
  2. Es wird eine Getter-Funktion erstellt, die dieses Ivar zurückgibt.

Der wichtige Teil bei Punkt 2 ist, dass standardmäßig das Ivar und die Getter-Funktion (und daher die Eigenschaft) die gleichen Namen haben.

Also wird dies:

@interface Event
@property(nonatomic, assign) NSUInteger timestamp;
@property(nonatomic, readonly, getter = timestamp) NSUInteger startTime;
@end

@implementation Event
@synthesize timestamp, startTime;
@end

...zu diesem:

@interface Event {
    NSUInteger timestamp;
    NSUInteger startTime;
}
@end

@implementation Event
- (NSUInteger) timestamp {
    return timestamp
}

- (void) setTimestamp:(NSUInteger) ts {
    timestamp = ts;
}

- (NSUInteger) startTime {
    return [self timestamp];
}
@end

Wie die Punktnotation funktioniert, ist folgendermaßen:

NSUInteger foo = myEvent.startTime;

bedeutet tatsächlich:

NSUInteger foo = [myEvent startTime];

Das alles soll sagen, dass, wenn Sie auf ein Ivar zugreifen, Sie auf ein Ivar zugreifen. Wenn Sie eine Eigenschaft verwenden, rufen Sie eine Funktion auf, die einen Wert zurückgibt. Noch wichtiger ist, dass es sehr einfach ist, das eine zu tun, wenn Sie eigentlich das andere gemeint haben, weil die Syntax so ähnlich ist. Aus diesem Grund synthetisieren viele Menschen routinemäßig ihre Ivars mit führenden Unterstrichen, damit es schwieriger ist, Fehler zu machen.

@property(nonatomic, assign) NSUInteger timestamp;
@property(nonatomic, readonly, getter = timestamp) NSUInteger startTime;

@synthesize timestamp = _timestamp;
@synthesize startTime = _startTime;

NSLog( @"startTime = %d", _startTime );  // OK, Zugriff auf das Ivar.
NSLog( @"startTime = %d", self.startTime );  // OK, Verwendung der Eigenschaft.
NSLog( @"startTime = %d", startTime );  // NEIN, das führt zu einem Kompilierfehler, und 
                                        // Sie werden "Huch" sagen und es dann zu einer der obigen Zeilen ändern, um 
                                        // potenziell stundenlanges Kopfzerbrechen zu vermeiden. :)

1voto

Joe Punkte 56389

Stellen Sie sicher, dass Sie in der richtigen Reihenfolge synthetisieren, damit der Getter für startTime vorhanden ist.

//Implementierung
@synthesize timestamp;
@synthesize statTime;

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X