我正在观看WWDC ARC介绍视频,之前我看到一些我从未在ObjC中看到的东西,当时一位Apple工程师谈到了Stack示例。
以下代码用于ARC的堆栈示例:
@implementation Stack
{
// instance variable declared in implementation context
NSMutableArray *_array;
}
- (id)init
{
if (self = [super init])
_array = [NSMutableArray array];
return self;
}
- (void)push:(id)x
{
[_array addObject:x];
}
- (id)pop
{
id x = [_array lastObject];
[_array removeLastObject];
return x;
}
@end
请注意在 @implementation 指令后立即声明的实例变量。
现在让我感到惊讶的是,实际变量实际上可以在实现文件中声明,而不是静态变量。我的问题如下:
答案 0 :(得分:40)
这确实是一种新的语言功能,如果你必须声明你的ivars(而不是简单地声明属性并让编译器为你生成ivars),这是一个很好的做法。理论上你的头文件应该只暴露你的类的公共接口;其他一切都属于实现。
有一点需要注意,实现文件ivars对于子类是不可见的,如果您手动生成了需要子类化的setter和getter,这有时会有点尴尬。
答案 1 :(得分:18)
在实现中声明iVars肯定是目标C中的新构造。 您需要使用xcode4.2并在构建设置中选择LLVM编译器。 我们的想法是让您的头文件更清晰。您可以在花括号内列出您的ivars 像这个例子;
@implementation MyClass {
int var1;
int var2;
}
Rahul给出的答案并不十分正确,尽管你可以通过编译器将变量视为静态的方式来推断变量。可能对于他使用它们的情况并不重要。
答案 2 :(得分:3)
我是Objective C的新手,我发现在标题中声明ivars的做法非常奇怪。它意味着在其公共头中声明对象的内部状态,这违背了封装的概念。
例如说你拥有一个iPad。 Apple不希望你打开iPad并撬开它,并且弄乱里面的元素。如果他们想要你修改某些东西,那么IPad将有一个让你改变它的设置。
同样地,我不希望其他程序员看到我的对象的ivars。它是我对象的内部状态。如果我希望你进入内部状态,我会为它声明属性。
所以,就像在其他语言中一样,我会将我的ivars隐藏在实现文件中,而不是在标题中声明它们。
在标题中声明ivars只是让我非常奇怪。 这些ivars是特定于实现的,并且应该不是头文件的一部分。