实例变量的实际名称,例如topSpeed,来自斯坦福大学关于Objective-C和iOS开发的讲座?
以下是代码:
@property (nonatomic) double topSpeed;
看看这段代码我会认为我已经在类中定义了一个变量topSpeed。 我无法理解为什么它会自动声明名称与变量名称相同的getter方法 - topSpeed?
另一个问题是我们何时使用
@synthesize topSpeed = _topSpeed
如果我们看一下@synthesize会产生什么:
- (double) setTopSpeed:(double)speed
{
_topSpeed = speed;
}
- (double) topSpeed
{
return _topSpeed;
}
这里的_topSpeed是什么,topSpeed是什么?我已经声明了一个变量topSpeed,而不是_topSpeed。如果我不使用属性变量名是什么怎么办?
答案 0 :(得分:39)
在Obj-C的早期阶段,今天你仍然在类的头文件中声明变量,如下所示:
@interface MySubclass : NSObject {
int varName;
}
然后你必须手动创建setter和getter方法来访问类外的变量。为了帮助处理内存管理(对对象有用),Apple在Obj-C 2.0中引入了属性,它允许您为给定变量定义访问器。您可以说变量具有某些属性(例如保留或复制值,具有备用setter或getter名称等),并且您将其定义为:
@property (someAttributes) int varName;
然后在@implementation中你可以用给定的属性@synthesize这些属性,编译器会为你的变量生成setter和getter方法。
@synthesize varName; // Generates -setVarName: and -varName for you
现在,今天的想法是你可以放弃在{}部分实现实例变量,只声明属性和合成。如果我们只说
,我们会得到什么@property (nonatomic) double topSpeed;
@synthesize topSpeed;
是一个setter和一个名为setTopSpeed的getter:和topSpeed,它带有一个名为topSpeed的实例变量(由编译器创建)来存储该值。 @synthesize topSpeed = _topSpeed;
背后的想法是实例变量名称为_topSpeed
,但访问者名称仍为-setTopSpeed:
和-topSpeed
。这有助于代码可读性,因为在您的代码中说self.topSpeed或topSpeed之间可能会产生混淆(第一个调用访问器,第二个调用ivar)。 _topSpeed将自己与普通变量区分开来,并且当你调用self.topSpeed(访问者)和_topSpeed(ivar)时也会使它显式化。 Apple正在转向这种下划线语法,所以不要认为它已经灭绝,因为它恰恰相反。更新:(见汤米的评论)
它还有助于变量命名冲突。如果你必须实现setTopSpeed:你自己看起来像这样:
- (void)setTopSpeed:(double)topSpeed {
_topSpeed = topSpeed; // _topSpeed makes it obvious it's an ivar
}
答案 1 :(得分:3)
@synthesize topSpeed = _topSpeed
表示您需要一个名为_topSpeed的变量,并且具有名为topSpeed和setTopSpeed的访问者。 @property (nonatomic) double topSpeed;
不是纯变量声明,它也会声明Accessors。类Foo的纯变量将如下所示:
@interface Foo:NSObject { double topSpeed; }
答案 2 :(得分:0)
对于第一个问题,答案是“命名约定”。所以它只是一个命名约定。如果您想访问topSpeed
变量,则“获取”部分并不重要 - 例如[car topSpeed]
比[car getTopSpeed]
更容易阅读。至于第二个问题,我不确定,但我相信您通过变量topSpeed
访问_topSpeed
属性。