Objective-C 属性 - getter 行为



以下技术上有什么问题:

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

我相信我可以找到更好的方法来组织它,但这就是我在项目中的某个时刻最终得到的,我注意到访问 startTime 属性总是返回 0,即使时间戳属性设置为正确的时间戳

似乎已将 startTime 的 getter 设置为现有属性(时间戳),当我这样做时,它不会转发时间戳的值:

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

顺便说一下,所有这些都是时间戳。

提醒一下,我知道上述情况应该发生在我的项目中,但我不明白为什么访问 startTime 不会转发到时间戳属性。

更新

在我的实现中,我正在合成所有这些属性:

@synthesize timestamp, endTime, startTime;

请检查一个示例对象,该对象在 GitHub 上的要点中演示了这一点:https://gist.github.com/3013951

在描述方法中,你没有使用该属性,而是在访问 ivar。

-(NSString*) description
{
    return [NSString stringWithFormat:@"Event< timestamp:%d, start:%d >", 
             timestamp, 
             startTime]; // <-- This is accessing the instance variable, not the property.
}

这将为您工作:

-(NSString*) description
{
    return [NSString stringWithFormat:@"Event< timestamp:%d, start:%d >", 
             timestamp, 
             self.startTime]; // <-- This is using the property accessor.
}

财产与伊瓦尔的事情总是把人们搞砸,所以请原谅我,当我漫无边际地谈论它一分钟时。 :) 如果您已经知道所有这些,请跳过。

如上所示,在创建和合成属性时,会发生两件事:

  1. 创建正确类型的 IVAR。
  2. 创建一个 getter 函数,该函数返回该 IVAR。

关于第 2 点的重要部分是,默认情况下,ivar 和 getter 函数(因此,属性)具有相同的名称

所以这个:

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

。变成这样:

@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

点语法的工作原理是:

NSUInteger foo = myEvent.startTime;

真的确实如此

NSUInteger foo = [myEvent startTime];

所有这些都表明,当您访问ivar时,您...好吧,访问 IVAR。 使用属性时,将调用返回值的函数。 更重要的是,当你的意思是另一件事时,做一件事非常容易,因为语法非常相似。 正是出于这个原因,许多人经常用前导下划线合成他们的 ivar,这样就更难搞砸了。

@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.  :)

确保以正确的顺序合成,以便 getter 存在startTime .

//implementation
@synthesize timestamp;
@synthesize statTime;

最新更新