What is technically wrong with the following:
@property(nonatomic, assign) NSUInteger timestamp;
@property(nonatomic, readonly, getter = timestamp) NSUInteger startTime;
@property(nonatomic, assign) NSUInteger endTime;
I am sure I can find a better way to organise this, but this is what I ended up with at one point in my project and I noticed that accessing the startTime property always returned 0, even when the timestamp property was set to a correct timestamp.
It seems having set the getter of startTime to an existing property (timestamp), it is not forwarding the value of timestamp when I do:
event.startTime => 0
event.timestamp => 1340920893
All these are timestamps by the way.
Just a reminder, I know the above should have happened in my project but I don't understand why accessing startTime doesn't forward onto timestamp property.
UPDATE
In my implementation I am synthesising all of these properties:
@synthesize timestamp, endTime, startTime;
Please check an example object to use that demonstrates this at my gist on GitHub: https://gist.github.com/3013951
In your description method, you aren't using the property, you're accessing the ivar.
-(NSString*) description
{
return [NSString stringWithFormat:@"Event< timestamp:%d, start:%d >",
timestamp,
startTime]; // <-- This is accessing the instance variable, not the property.
}
This will work for you:
-(NSString*) description
{
return [NSString stringWithFormat:@"Event< timestamp:%d, start:%d >",
timestamp,
self.startTime]; // <-- This is using the property accessor.
}
The property-vs-ivar thing messes people up all the time, so excuse me while I ramble on about it for a minute. :) If you already know all of this, skip ahead.
When you create and synthesize a property, as you did above, two things happen:
The important part about point 2 is that, by default, the ivar and the getter function (and therefore, the property) have the same names.
So this:
@interface Event
@property(nonatomic, assign) NSUInteger timestamp;
@property(nonatomic, readonly, getter = timestamp) NSUInteger startTime;
@end
@implementation Event
@synthesize timestamp, startTime;
@end
...turns into this:
@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
How dot syntax works is that this:
NSUInteger foo = myEvent.startTime;
really does
NSUInteger foo = [myEvent startTime];
All of that to say that when you access an ivar, you're... well, accessing an ivar. When you use a property, you're calling a function which returns a value. More importantly, it's exceedingly easy to do one thing when you meant the other, because the syntax is so very similar. It's for this reason that many people routinely synthesize their ivars with leading underscores, so that it's harder to mess up.
@property(nonatomic, assign) NSUInteger timestamp;
@property(nonatomic, readonly, getter = timestamp) NSUInteger startTime;
@synthesize timestamp = _timestamp;
@synthesize startTime = _startTime;
NSLog( @"startTime = %d", _startTime ); // OK, accessing the ivar.
NSLog( @"startTime = %d", self.startTime ); // OK, using the property.
NSLog( @"startTime = %d", startTime ); // NO, that'll cause a compile error, and
// you'll say "whoops", and then change it
// to one of the above, thereby avoiding
// potentially hours of head-scratching. :)
Make sure you synthesize in the correct order so the getter exists for startTime
.
//implementation
@synthesize timestamp;
@synthesize statTime;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With