Xcode 4.5 中@property 和 ivar 的区别
Posted
技术标签:
【中文标题】Xcode 4.5 中@property 和 ivar 的区别【英文标题】:Difference between @property and ivar in Xcode 4.5 【发布时间】:2012-10-08 23:17:28 【问题描述】:以前我总是看到像这样使用属性和 iVar 的例子......
在 SomeClass.h 中
@interface SomeClass : NSObject
NSString *_someString;
@property NSString *someString;
@end
然后在 SomeClass.m
#import "SomeClass.h"
@implementation SomeClass
@synthesize someString = _someString;
@end
最近(在 WWDC 2012 视频中)我听说我们不再需要 @synthesize
,建议只使用不关联 iVar 的 @property
。
所以上面会变成...
SomeClass.h
@interface SomeClass : NSObject
@property NSString *someString;
@end
SomeClass.m
#import "SomeClass.h"
@implementation SomeClass
@end
这只是使用@property
而没有 ivar。这是有道理的,我一直在使用它。
不过,我也看到过……的例子
SomeClass.h
@interface SomeClass : NSObject
@end
SomeClass.m
#import "SomeClass.h"
@interface SomeClass ()
NSString *someString;
@end
@implementation SomeClass
@end
在此他们只有一个私人iVar
而没有@property
。
那么有什么区别呢?我知道@property
也提供了访问器方法,但您不必重写访问器方法。您可以只使用默认访问器。
那么什么时候你会使用@property 而不是ivar,什么时候你会只使用ivar 而不是@property
?为什么不完全摆脱 ivars 而只使用@properties
?如果它们需要私有,那么只需在 .m 的接口扩展中使用它们。
快速编辑以响应有关内存管理的答案。我正在使用 ARC,对我来说,使用 strong
和 weak
@properties
似乎比使用 iVars 可以更好地控制内存管理。
我希望问题足够清楚。
谢谢
【问题讨论】:
请注意,上面的第一个示例很糟糕。在其中,您有一个someString
属性和一个名为 _someString
的默认支持 iVar 和第二个与该属性没有连接但命名为 someString
的 iVar,只是为了引起痛苦。 :-)
@Phillip Mills,现在更正了。
@property
使您能够在常规 iVar 无法使用的情况下使用 KVO。除了你已经提到的,我不知道任何其他优点/缺点。
基本上,两者都可以访问相同级别的内存管理。 iVar 没有 getter 和 setter,而属性有。属性允许使用 KVO 而 iVar 不允许。然后我会坚持使用属性:D
【参考方案1】:
通常,您始终可以使用属性。如果您有“分配”属性,您可以使用 ivar,因为您不需要在 getter/setter 中进行任何内存管理。但是,如果您应该保留对象,那么使用 ivars 很不方便,因为您必须手动保留/释放它们,而属性会为您执行此操作。
此外,如果您使用 ivars,您将无法控制设置/获取值。一般来说,使用公共字段而不是 getter 或 setter 是一种不好的做法。例如,如果您可以为存储人员年龄的字段设置负值,则不可以。
你不能将 KVO 与 ivars 一起使用
【讨论】:
但如果我使用的是 ARC,那么这一切都为我完成了。对我来说,使用强和弱属性似乎可以让我获得更多的内存控制,而根本不必使用 iVar。 您当然可以说__weak NSString* _string
并拥有与@property (weak) NSString* string
相同的控制级别
1) 如果您使用 ivars,您将无法控制设置/获取值。一般来说,使用公共字段而不是 getter 或 setter 是一种不好的做法。例如,如果您可以为存储人员年龄的字段设置负值,则不可以。 2)您不能将 KVO 与 ivars 一起使用
谢谢,我想我会坚持使用@properties :D 无论如何我都有这样的想法,但我认为这里的回复证实了我的决定:D
我用评论中的信息更新了我的答案,以涵盖属性的更多优势:)【参考方案2】:
我认为这取决于您可以使用“->
”语法访问公共 ivars 的事实。
也许以前,如果您声明一个没有@private
ivar 的只读属性,您可以访问
使用“->
”语法对其 ivar。 (也许它打破了封装)。
但是现在如果你声明这样的东西
@private NSArray *a;
@protected NSArray *b;
@public NSArray *c;
@property (nonatomic, retain) NSArray *d;
你只能用“->
”访问“c
”ivar,试试这个代码。
使用 a,b 和 d 将是警告或错误。
如果有帮助的话,我会很高兴的。
【讨论】:
以上是关于Xcode 4.5 中@property 和 ivar 的区别的主要内容,如果未能解决你的问题,请参考以下文章
UIPageViewController 使用 Storyboard 和 Xcode 4.5