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,对我来说,使用 strongweak @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 的区别的主要内容,如果未能解决你的问题,请参考以下文章

在 Xcode 6 和 Xcode 4.5 之间切换

UIPageViewController 使用 Storyboard 和 Xcode 4.5

并排安装 xcode 4.4 和 xcode 4.5?

如何在 xcode 4.5 中选择数据源和委托?

iOS 项目将 Xcode 4.2 更新到 Xcode 4.5

如何在 xcode 4.5 中选择一个 .app 项目?