Objective-C属性 - getter行为

时间:2012-06-28 20:31:01

标签: objective-c properties getter

以下内容在技术上有什么问题:

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

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

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

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

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

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

更新

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

@synthesize timestamp, endTime, startTime;

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

2 个答案:

答案 0 :(得分:6)

在您的描述方法中,您没有使用该属性,而是访问了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函数,返回该函数。
  3. 关于第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。当您使用属性时,您正在调用一个返回值的函数。更重要的是,当你指的是另一个时,做一件事非常容易,因为语法非常相似。正是由于这个原因,许多人经常将他们的ivars与领先的下划线合成,所以它更难搞乱。

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

答案 1 :(得分:1)

确保以正确的顺序合成,因此startTime存在getter。

//implementation
@synthesize timestamp;
@synthesize statTime;