繁体   English   中英

Objective-C合成属性名称覆盖

[英]Objective-C synthesize property name overriding

我试图理解具有属性名称重写的synthesize指令的目的。 假设我有一个接口定义如下:

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

@property (retain, nonatomic) UILabel *dummyLabel;

在实现文件中,我有:

@synthesize dummyLabel = _dummyLabel;

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

是。 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

你的理解是不正确的。 dummyLabel是属性的名称, 不是实例变量的别名 - 实例变量称为_dummyLabel 因此,以下适用于名为myObjectDummy实例:

  • [myObject dummyLabel]有效
  • myObject.dummyLabel有效
  • [myObject _dummyLabel]失败
  • myObject._dummyLabel失败
  • myObject->dummyLabel失败
  • myObject->_dummyLabel依赖于的ivar的可见性( @public@private@protected
  • [myObject valueForKey: @"dummyLabel"]有效
  • [myObject valueForKey: @"_dummyLabel"]取决于+accessInstanceVariablesDirectly [myObject valueForKey: @"_dummyLabel"]的实现(即它将在​​默认情况下工作,其中+accessInstanceVariablesDirectly返回YES )。

使用ivar的另一个名称而不是属性的优点是,当您访问其中一个或另一个时,您可以在代码中轻松查看 - Andre 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之间的区别不仅仅是语义。

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

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

最后一段:

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM