如果obj-c类中存在getter,为什么没有找到ivar?

时间:2014-05-23 13:30:44

标签: objective-c properties

我有一个非常简单的类ExampleTrack,其属性为duration。我想自己实现这个属性的getter和setter。我的问题是我遇到编译器错误,声称_duration(ivar)未声明。这是我的代码:

ExampleTrack.h:

#import <Foundation/Foundation.h>

@interface ExampleTrack : NSObject

@property (nonatomic) Float32 duration;

@end

ExampleTrack.m

#import "ExampleTrack.h"

@implementation ExampleTrack

-(void)setDuration:(Float32)duration {
    _duration = duration; // compiler error: Use of undeclared identifier '_duration'; did you mean 'duration'?
}

-(Float32)duration {
    return _duration; // compiler error: Use of undeclared identifier '_duration'
}

@end

最有趣的部分是,如果我删除了getter,那么setter编译得很好。

这里有什么问题?

1 个答案:

答案 0 :(得分:3)

这很棘手,因为自动合成的实例变量的自动命名的规则会根据具体情况而变化。

  • 如果您没有getter或setter且没有明确的@synthesize,但只是让所有内容自动合成,那么(现在)名为prop的属性会获得一个ivar _prop

  • 但是如果你自己提供getter和setter而没有明确的@synthesize,那么没有会自动发生:特别是,ivar不是自动合成的(你必须声明ivar明确地)。这部分是为了向后兼容,部分是因为如果你同时提供getter和setter,编译器会假定你处于(并希望)完全控制。在这种情况下甚至可能没有静脉注射; getter / setter可能完全是其他东西的“前线”。

有两个“解决方案”(假设你想同时保留getter和setter):

  • 宣布伊娃。您可以将ivar命名为任何您喜欢的名称,您可以在getter和setter中引用它(我喜欢self->_ivar语法)。

  • 撰写明确的@synthesize语句。这允许您指定编译器将为您创建的ivar的名称。