Objective-C合成属性名称覆盖

时间:2010-09-27 10:16:05

标签: objective-c synthesizer

我试图了解具有属性名称覆盖的synthesize指令的用途。假设我有一个接口定义如下:

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

@property (retain, nonatomic) UILabel *dummyLabel;

在实施文件中,我有:

@synthesize dummyLabel = _dummyLabel;

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

5 个答案:

答案 0 :(得分:24)

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

Dot语法扩展为简单的方法调用,因此它不是特定于属性的。如果您有一个名为-(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

答案 1 :(得分:17)

您的理解不正确。 dummyLabel是属性的名称,不是实例变量的别名 - 实例变量名为_dummyLabel。因此,以下适用于名为Dummy的{​​{1}}实例:

  • myObject正常工作
  • [myObject dummyLabel]正常工作
  • myObject.dummyLabel失败
  • [myObject _dummyLabel]失败
  • myObject._dummyLabel失败
  • myObject->dummyLabel取决于ivar的可见性(myObject->_dummyLabel@public@private
  • @protected正常工作
  • [myObject valueForKey: @"dummyLabel"]取决于[myObject valueForKey: @"_dummyLabel"]的实施(即,它将在默认情况下+accessInstanceVariablesDirectly返回+accessInstanceVariablesDirectly)。

答案 2 :(得分:13)

  

拥有另一个名字的优势   对于伊娃而言,比财产是   你可以在代码中轻松看到   当你访问一个或   其他 - 安德烈·K

我无法找到“评论”按钮,因此我不得不将其作为“回答”发布。

只是想扩展Andre的评论 - 通过知道你何时使用合成属性vs vanilla变量,你知道(特别是在setter的情况下)当一个变量被保留/复制/释放时,由于你的好setter ,vs被手工操纵。

当然,如果你做得对,你可能不需要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,您确切知道会发生什么

_autoLoginOnself.autoLoginOn之间的差异不仅仅是语义上的。

答案 3 :(得分:0)

  

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

在某些ObjC运行时中,您很难让实例变量对类的用户不可见。对于他们在您的实例变量上添加一些前缀(或后缀)可以使您明确(或更清楚)您不希望任何人弄乱您的变量。但是你不希望你的公共功能上有那些垃圾。这可以让你把它取下来。

如果您需要使用一组新名称(setLastname与setSurname)同时维护一个带有一组名称的旧接口,这也很有用。

答案 4 :(得分:0)

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

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

最后一段:

  

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