15

我试图通过synthesize覆盖属性名称来理解指令的目的。假设我有一个定义如下的接口:

@interface Dummy ... {
    UILabel *_dummyLabel;
}

@property (retain, nonatomic) UILabel *dummyLabel;

在实现文件中,我有:

@synthesize dummyLabel = _dummyLabel;

据我了解,“dummyLabel”只是实例变量“_dummyLabel”的别名。self._dummyLabel 和 self.dummyLabel 有什么区别吗?

4

5 回答 5

24

是的。self._dummyLabel是未定义的,但_dummyLabel不是。

点语法扩展到简单的方法调用,因此它不特定于属性。如果你有一个方法被调用-(id)someObject,例如在的情况下object.someObject,它会像你写的一样[object someObject];

self.dummyLabel  //works
self._dummyLabel //does not work
dummyLabel       //does not work
_dummyLabel      //works
[self dummyLabel];  //works
[self _dummyLabel]; //does not work
于 2010-09-27T10:17:28.023 回答
17

你的理解是不正确的。dummyLabel是属性的名称,而不是实例变量的别名 - 实例变量被调用_dummyLabel。因此,以下适用于Dummy被调用的实例myObject

  • [myObject dummyLabel]作品
  • myObject.dummyLabel作品
  • [myObject _dummyLabel]失败
  • myObject._dummyLabel失败
  • myObject->dummyLabel失败
  • myObject->_dummyLabel取决于 ivar ( @public, @private, @protected)的可见性
  • [myObject valueForKey: @"dummyLabel"]作品
  • [myObject valueForKey: @"_dummyLabel"]取决于的实现+accessInstanceVariablesDirectly(即它将在+accessInstanceVariablesDirectly​​返回的默认情况下工作YES)。
于 2010-09-27T10:23:43.540 回答
13

为 ivar 使用另一个名称而不是属性的优点是,当您访问其中一个或另一个时,您可以在代码中轻松看到 - Andre K

我找不到“评论”按钮,所以我不得不发布为“答案”。

只是想扩展安德烈的评论-通过了解您何时使用合成属性与普通变量,您知道(尤其是在设置器的情况下)何时自动保留/复制/释放变量,这要归功于您的好设置器,而不是用手操纵。

当然,如果你做对了,你可能不需要 setter 的帮助来正确地保留/释放对象!但是在其他情况下,将您的 ivars 称为self.ivar而不是_ivar可能会有所帮助,例如当您使用自定义 setter/getter 而不是默认的合成方法时。也许每次你修改一个属性时,你也想把它存储到 NSUserDefaults 中。所以你可能有一些这样的代码:

@interface SOUserSettings : NSObject {

BOOL _autoLoginOn;

}

@property (nonatomic, assign) BOOL autoLoginOn;

@end

@implementation SOUserSettings

@synthesize autoLoginOn = _autoLoginOn;

- (void)setAutoLoginOn:(BOOL)newAutoLoginOnValue {

   _autoLoginOn = newAutoLoginOnValue;
   [[NSUserDefaults standardUserDefaults] setBool:_autoLoginOn forKey:@"UserPrefAutoLoginOn"];
}

@end

注意:这只是说明性代码,它可能有一千个错误!

所以现在,在你的代码中,如果你有一行说_autoLoginOn = YES- 你知道它不会被保存到 NSUserDefaults,而如果你使用self.autoLoginOn = YES你就知道会发生什么。

_autoLoginOn和之间的区别self.autoLoginOn不仅仅是语义上的。

于 2011-04-22T05:10:27.143 回答
0

我看不到将 _dummyLabel 重命名为 dummyLabel 的任何大优势

在某些 ObjC 运行时中,您很难使实例变量对类的用户不可见。对于他们来说,在您的实例变量上添加一些前缀(或后缀)可以明确(或更清楚)您不希望任何人弄乱您的变量。但是,您不希望在您的公共职能上出现这种情况。这可以让你摆脱它。

如果您需要同时维护具有一组名称的旧接口以及具有一组新名称的新 API 集(setLastname 与 setSurname),它也可能很有用。

于 2010-09-27T13:36:16.703 回答
0

旧帖子,但我认为值得一提的是,建议通过 getter 和 setter 访问变量(因此,使用点表示法)。强烈建议仅在初始化时直接访问字段 (_ivar)。

有一些很好的苹果文章: https ://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html

最后一段:

您应该始终直接从初始化方法中访问实例变量,因为在设置属性时,对象的其余部分可能尚未完全初始化。即使您不提供自定义访问器方法或不知道您自己的类中的任何副作用,未来的子类也很可能会覆盖该行为。

于 2013-03-12T18:14:05.483 回答