我应该在接口中声明变量还是在objective-c arc中使用属性?

Posted

技术标签:

【中文标题】我应该在接口中声明变量还是在objective-c arc中使用属性?【英文标题】:Should I declare variables in interface or using property in objective-c arc? 【发布时间】:2012-12-23 14:14:43 【问题描述】:

方法一:

@interface MyController : UIViewController 
    UILabel *myText;


@property (nonatomic, strong) UILabel *myText;

方法二:

@interface MyController : UIViewController
@property (nonatomic, strong) UILabel *myText;

方法3:

@interface MyController : UIViewController 
    UILabel *myText;

我已经阅读了一些关于这类东西的文章,但我仍然没有真正意识到我必须采用哪种方法。

我还发现有人说方法 1 是一种旧方法,所以我想知道使用 ARC 的 ios sdk 6 的最佳实践。

我知道使用属性声明变量是生成 getter 和 setter 的一种简单方法,有人建议使用它。但是,我想问一下,如果一个变量不是由另一个类调用的,那么这个变量是否需要使用属性?并将其设置为接口内的私有变量?或者对于仅在接口内声明的变量更好?我想学习最佳实践,如果这是一个愚蠢的问题,请原谅我。

另外,有些开发者是这样写@synthesize的

@synthesize myText=_myText;

但有些人会这样写:

@synthesize myText;

我也想知道区别,哪个更可取?

非常感谢!

【问题讨论】:

你所有的合成方法,在最后的 XCode 版本中没有合成将属性连接到名为 _myText 的 ivar,而不是 myText 【参考方案1】:

最现代的方式1

尽可能声明属性 不要单独声明 iVars 2 不要@synthesize 3 在你的.h文件中找到尽可能少的属性4 在 .m 文件的类扩展中找到尽可能多的属性5

1 从 Xcode 4.5.2 开始。其中大部分适用于 4.4,其中一些不会在 4.2(Snow Leopard 下可用的最后一个版本)上编译。这是预处理器的东西,所以它至少兼容 iOS5(我没有在 iOS4 上测试过,但应该没问题)。

2 声明一个iVar 以及一个属性是没有意义的。我确信有一些模糊的情况,您希望声明 iVars 而不是 属性,但我想不出任何。

3 Xcode 将创建一个与属性同名的 iVar,前面有一个 _underscore。如果您(很少)需要其他类型的行为,您可以手动@synthesize property = someOtherName。 @vikingosegundo 将我们链接到this article on dynamic ivars,这是@synthesize 的一个用例。 @RobNapier cmets 你需要@synthesize iVar = _iVar(奇怪地)如果你正在为一个属性创建你自己的getter(只读)和setter(读/写),因为在这种情况下预处理器不会为您生成 iVar。

4 界面的一般规则:尽可能保持空白。你现在根本不需要声明你的方法,如果它们是供私人使用的。如果您可以在没有接口声明的情况下使代码工作,那就是要走的路。

5 这是.m 文件中的@interface 块,位于@implementation 上方:

#TestClass.m

@interface TestClass()

//private property declarations here

@end

@implementation TestClass
...

【讨论】:

@Eric 请给我点赞。 @synthesize 不再需要(Xcode 4.5+),编译器知道在没有它的情况下生成 getter 和 setter。您不需要手动生成它们或@synthesize 对,@synthesize 属于恐龙。 @aknew,是的,这是错误的。您应该使用在 .m 文件中声明的属性。但是您仍然应该使用访问器,即使在内部也是如此。除了 init 和 dealloc 之外,您应该在任何地方使用访问器。 很好的答案,但在一种情况下您确实需要使用合成。如果你实现了所有需要的访问器的自定义版本(getter for readonly,getter/setter for readwrite),clang 不会自动为你生成 ivar。所以你需要包含一个“@synthesize var=_var;”手动请求它。 访问器的语义是访问状态。它在内部和外部都具有适当的语义。访问器也应该专门用于实际原因,包括支持 KVO 和子类化。直接访问 ivars 是导致 ARC 前错误的主要原因。在 ARC 之后,文档和体验中继续推荐它。 “你不应该使用访问器方法来设置实例变量的唯一地方是初始化方法和dealloc。” developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/…【参考方案2】:

如果您喜欢@synthesized 属性的漂亮目录,您可能还想使用@synthesize,您可以参考和评论以便清晰和组织。

此外,@synthesize 允许您在属性上设置断点并在其值更改时捕获。

当编译器为您完成所有事情时,您最终会远离真正发生的事情并且对它一无所知。但是,不必一直自己输入所有内容也很好。

【讨论】:

以上是关于我应该在接口中声明变量还是在objective-c arc中使用属性?的主要内容,如果未能解决你的问题,请参考以下文章

为啥/何时应该使用静态声明变量?

我应该在声明中还是在构造函数中实例化实例变量?

在 Java 中,变量应该在函数的顶部声明,还是在需要时声明?

在java中应该在循环内还是循环外声明变量[重复]

Objective-C——属性与成员变量辨析

第8章 继承(Objective-C程序设计)