【问题标题】:Objective-C property and synthesize logicObjective-C 属性和综合逻辑
【发布时间】:2012-03-03 07:26:54
【问题描述】:

在斯坦福大学关于 Objective-C 和 iOS 开发的讲座中,实例变量的实际名称是什么,比如 topSpeed?

代码如下:

@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。如果我不使用属性怎么办?变量名是什么?

【问题讨论】:

标签: objective-c properties


【解决方案1】:

在 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 和一个 getter,称为 setTopSpeed: 和 topSpeed,带有一个名为 topSpeed 的实例变量(由编译器创建)来存储值。 @synthesize topSpeed = _topSpeed; 背后的想法是实例变量名称将是 _topSpeed,但访问器名称仍将是 -setTopSpeed:-topSpeed。这有助于代码的可读性,因为在代码中说 self.topSpeed 或 topSpeed 时可能会产生混淆(第一个调用访问器,第二个是 ivar)。 _topSpeed 将自己与普通变量区分开来,并且在您调用 self.topSpeed (访问器)与 _topSpeed (ivar)时也使其明确。苹果也在转向这种下划线语法,所以不要认为它会灭绝,因为它恰恰相反。更新:(见汤米的评论)

它还有助于解决变量命名冲突。如果你必须自己实现 setTopSpeed: 它看起来像这样:

- (void)setTopSpeed:(double)topSpeed {
    _topSpeed = topSpeed; // _topSpeed makes it obvious it's an ivar
}

【讨论】:

  • ... 而现在@synthesize topSpeed = _topSpeed 隐含在相关的@property 中;实际上没有必要包含它。你可以包含一个替代的@synthesize(例如,指定一个没有前导下划线或完全与属性无关的实例变量名称)或自己编写getter/setter(例如,如果你想调用[self setNeedsLayout]当属性改变时),但如果你什么都不提供,那么编译器将推断出通常的@synthesize
  • self.topSpeed 或 topSpeed 在您的代码中(它们是两个不同的东西) 这是两个不同的东西,因为topSpeed 是其值由@ 返回的实例变量987654336@房产?
  • 我不明白,即使它不是属性而是实例变量。我们不能设置和获取实例变量的值吗?我的意思是我们如何设置和获取实例变量的值?
  • @asma22 如果您在实现 (.m) 中声明实例变量,那么您只能在该类中访问。如果您想让它公开访问,那么您需要在界面 (.h) 中创建一个属性。
【解决方案2】:
  1. 它是一种语法糖,让您输入更少的单词。
  2. 不同于 java/c++,在 obj-c 中你不能访问类的变量。你只能调用它的方法。
  3. @synthesize topSpeed = _topSpeed 表示您需要一个名为 _topSpeed 的变量,并拥有名为 topSpeed 和 setTopSpeed 的访问器。
  4. @property (nonatomic) double topSpeed; 不是纯变量声明,它也会声明访问器。 Foo 类的纯变量如下所示:

    @interface Foo:NSObject{ 双顶速度; }

【讨论】:

  • "与 java/c++ 不同,在 obj-c 中你不能访问类的变量。"如果你的意思是实例变量,如果它们是@public,你可以直接在Objective-C中访问它们。
【解决方案3】:

第一个问题的答案是“命名约定”。所以这只是一个命名约定。如果你想访问topSpeed 变量,“get”部分并不重要——比如[car topSpeed][car getTopSpeed] 更容易阅读。至于第二个问题,我不确定,但我相信您通过变量_topSpeed 访问topSpeed 属性。

【讨论】:

    猜你喜欢
    • 2012-09-23
    • 2012-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多