省略属性的 ivars 声明是否会导致麻烦或泄漏?
我开始针对iOS4进行学习和开发,所以我只是跳过了旧的ivar声明约定,开始使用纯属性,甚至没有声明ivars。一切都很顺利,我什至在应用商店发布了我的第一个自制应用程序。但后来在我的开发公司,人们告诉我他们仍在使用旧的约定,并使用下划线名称声明 ivars,使用属性并合成它们(请参阅最后的示例)。他们还表示,仅当需要外部访问 ivars 时才使用属性,而对于内部访问,他们使用直接 ivars(用于自定义类)。有人告诉我,他们这样做是因为他们遇到了一些奇怪的泄漏,这些泄漏有时会在使用自定义类并在 viewDidUnload 中取消其属性时出现(因为将 nil 设置为属性有时不会释放这些 ivar 对象)
只是想知道为什么应该在使用属性和合成时,我费心使用 ivar 声明来完成所有需要的事情。我什至可以直接使用它们的名称来访问 ivars,而无需在 dealloc 中使用 self。那么,有人对此有疑问吗?或者你们中的许多人仍然坚持旧的声明约定?
@interface ContactModel : NSObject {
NSString *_firstName;
}
@property (nonatomic, retain) NSString *firstName;
@end
@implementation ContactModel
@synthesize firstName = _firstName;
-(void)dealloc{
[_firstName release];
[super dealloc];
}
@end
还应该注意的是,Apple 在生成主应用程序委托类文件并合成 window=_window 时仍然使用旧的声明样式。嗯,目前,我对应该采取什么约定有点困惑,所以欢迎任何想法:)
I started to learn and develop for iOS4, so I just skipped the old ivar declaration convention and started to use pure properties without even declaring ivars. Everything went fine, I even released my first homemade app on the app store. But then at my dev company, guys told me that they are still using old convention and are declaring ivars with underscored names, use properties and synthesize them (see example at the end). They also said that they are using properties only when outside access to ivars is needed, and for inner access they use direct ivars (for custom classes). I was told that they are doing so because they were experiencing some weird leaks, that sometimes appeared when using custom classes and nil'ying their properties in viewDidUnload (because setting nil to properties sometimes didn't release those ivar objects)
Just wondering why should I bother to use ivar declaration when using properties and synthesize does all the needed stuff. I can even access ivars directly using their names without self in dealloc. So, does anybody got problems with that or many of you still are sticking with the old declaration convention?
@interface ContactModel : NSObject {
NSString *_firstName;
}
@property (nonatomic, retain) NSString *firstName;
@end
@implementation ContactModel
@synthesize firstName = _firstName;
-(void)dealloc{
[_firstName release];
[super dealloc];
}
@end
Should also note, that Apple still uses that old declaration style when generating main app delegate class file and synthesize window=_window. Hm, currently, I'm a little bit confused about what convention should I take, so any ideas are welcome :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在现代运行时,您不需要 ivar 声明,但合成 a=_a 仍然有助于区分 self.a (访问器)和 _a (直接访问)。如果 @property/@synthesize 泄漏了,我想我们现在应该知道了。
据我所知,仅当您想要 @protected 访问(仅访问子类)或支持旧运行时时,使用 ivars 而不是属性才有用。
在 dealloc 中,无论您是否使用 ivar 声明和 @properties,都应该直接释放该属性,并且可以选择 你可以为零或不。
In the modern runtime you don't need the ivar declaration, but synthesize a=_a is still useful to make a distinction between self.a (accessors) and _a (direct access). If @property/@synthesize was leaking I think we should know it by now.
AFAIK using ivars instead properties is only useful if you want @protected access (access to subclasses only), or support the old runtime.
In dealloc you should release the property directly whether you are using ivar declaration and @properties, and optionally you can nil or not.
我喜欢“老方法”,因为我喜欢一致性和(更重要的是)封装。
一致性
就我个人而言,我只是想通过查看一个地方来很好地了解对象的大小和复杂性。
示例:当您实现 dealloc 时,您是否更喜欢引用多个位置?不是我。这比必要的更复杂。我不想通过从所有 ivars 和属性创建一个集合来弄清楚我需要清理什么。单独的属性是不够的,因为它们最终也会出现在多个地方(接口、私有类别)=\,
所以在我看来,较小的邪恶是声明 ivars,这样所有的东西都在一个地方,你可以快速引用对象的复杂性(以及对于某些代码生成器来说是一个很好的输入)。
封装
当你看到一个程序,其中大多数对象的ivars/属性都是可见的并且是可读/可写的......这不是OOD,而是一团糟。当你需要礼貌地描述它时,它就是反模式“对象狂欢”。不幸的是,它在 objc 程序中相对常见(部分由于语言/运行时限制)。
带有前缀下划线的 ivars:就个人而言,我不在 objc 中使用该约定。如果他们的代码就是这样写的,那就用它吧(没什么大不了的)。
正确 - 这就是尝试封装的地方。顺其自然并接受适当的封装。
理想情况下,他们会为您提供了更好的解释(并找到了当时具体问题的根源)。
他们的神秘程序很可能没有对其成员(数据)、接口及其执行做出足够清晰的区分。当这些重叠时,失去所有权的情况并不少见。这种情况是组织混乱和/或实施超出预期的普遍迹象。如果你正确地组织/编写类,ivar/属性跟踪非常简单(大概,他们通过支持封装而取得了进展)。同样,protected 是默认可见性;我建议您将 private 作为默认值。
所以...我认为他们提出这个请求是为了通过减少对状态的外部暴露并最终减少程序的复杂性来使您的生活更简单。他们承认过去遇到过问题,并且正在尝试使用封装来降低复杂性和出错的机会。对他们有好处。
我知道,有些程序员只是喜欢所有公开可见和可变的东西 - 编写程序来支持这种复杂程度并不是对时间的有效利用,而现实是大多数这样做的人都这样写如果没有远见或耐心来正确编写这样的程序,就会给其他人带来麻烦。当然,它过去可能对您有用,但这是一种幼稚的方法,当您与团队合作时,您没有机会编写所有程序。因此,你不能假设他们已经完整地阅读并理解了你编写的每个程序。
通过隐藏您可以隐藏的内容,使您的程序具有用户/防错性,并使它们与您团队的风格保持一致。
(从技术上讲还有一些额外的好处,我不会在这里详细说明)
i favor the 'old way' because i favor consistency and (more importantly) encapsulation.
Consistency
personally, i just want a good idea of the object's size and complexity by looking one place.
example: when you implement dealloc, do you prefer to refer to multiple places? not me. it's more complicated than is necessary. i don't want to figure out what i need to cleanup by creating a set from all ivars and properties. properties alone are not enough because they also end up in multiple places (interface, private categories) =\
so the lesser evil imo is to declare ivars so everything is in one place and you have a quick reference to the object's complexity (as well as a good input for some code generators).
Encapsulation
when you see a program where most objects' ivars/properties are visible and read/writable... that's not OOD, it's a mess. when you need to describe it politely, it's the anti-pattern 'Object Orgy'. unfortunately, it's relatively common in objc programs (partly due to language/runtime restrictions).
ivars with prefixed underscores: personally, i don't use that convention in objc. if that's how their code is written, then go with it (not a big deal).
right - here's where attempts at encapsualtion enter the picture. go with it and embrace proper encapsulation.
ideally, they would have provided you with a better explanation (and gotten to the root of the specific problem at the time).
it's likely that their mystery program(s) did not make a clear enough distinction from its members (data), interface, and its execution. when those overlap, it's not uncommon to lose track of ownership. that case is a general sign of disorganization and/or an implementation extending beyond expectations. if you organize/write classes properly, ivar/property tracking is dead simple (presumably, they are making progress by favoring encapsualtion). as well, protected is the default visibility; i recommemnd private as your default.
so... i see it as they are making this request to make your life simpler by reducing external exposure to state and ultimately to the program's complexity. they have admitted to having had problems in the past, and they are trying to use encapsulation to reduce complexity and chances for errors. good for them.
i know, some programmers just prefer everything publicly visible and mutable - writing programs to support that level of complexity is not an effective use of time, and the reality is that the majority of the people who do write that way don't have the foresight or patience to actually write such a propgram correctly and it then causes headaches for others. sure, it may have worked for you in the past, but it is a naive approach and you don't have the luxury of writing all the programs when you work with a team. therefore, you can't assume they have read and understand every program you write in its entirety.
make your programs user/error-resistant by hiding what you can, and make them consistent with your team's style.
(there are technically a few additional benefits, which i'll not detail here)