在ObjC实现文件中声明的实例变量

时间:2011-07-22 04:48:11

标签: objective-c automatic-ref-counting

我正在观看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 指令后立即声明的实例变量。

现在让我感到惊讶的是,实际变量实际上可以在实现文件中声明,而不是静态变量。我的问题如下:

  • 这是iOS 5 SDK中引入的一些新构造还是已经可以使用了很长时间?
  • 如果不在对象外部访问实例变量,那么在实现中声明实例变量是不错的做法?它似乎比使用@private指令更清洁。

3 个答案:

答案 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是特定于实现的,并且应该不是头文件的一部分。