[英]Overriding property accessor names in Objective-C with @synthesize
[英]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
。 因此,以下适用于名为myObject
的Dummy
实例:
[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
你就知道会发生什么。
_autoLoginOn
和self.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.