48

我正在观看 WWDC ARC 介绍视频,当一些 Apple 工程师谈到 Stack 示例时,我看到了以前在 ObjC 中从未见过的东西。

以下代码用于 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 指令更干净。
4

3 回答 3

40

这确实是一个新的语言特性,如果您必须声明您的 ivars(而不是简单地声明属性并让编译器为您生成 ivars),这是一个很好的做法。理论上你的头文件应该只为你的类公开公共接口;其他一切都属于实施。

一个警告是实现文件 ivars 对子类不可见,如果您手动生成需要子类化的 setter 和 getter,这有时会有点尴尬。

于 2011-07-31T18:12:20.030 回答
18

在实现中声明 iVars 绝对是目标 C 中的一个新结构。您需要使用 xcode4.2 并在构建设置中选择 LLVM 编译器。这个想法是让你的头文件更干净。你可以像这个例子一样在花括号内列出你的 ivars;

@implementation MyClass {    
  int var1;
  int var2;
}

Rahul 给出的答案并不真正正确,尽管您可以按照他所说的方式对变量进行 delare,编译器会将它们视为静态变量。可能对于他使用它们的情况来说,这并不重要。

于 2011-08-03T12:28:28.190 回答
3

我是 Objective C 的新手,我发现在标题中声明 ivars 的做法非常奇怪。这意味着在其公共标头中声明对象的内部状态,这违背了封装的概念。

例如,假设您拥有一台 iPad。Apple 不希望你打开 iPad 并四处撬动,弄乱里面的元素。如果他们想让你修改某些东西,iPad 会有一个设置让你改变它。

同样,我不希望其他程序员看到我的对象的 ivars。它是我对象的内部状态。如果我希望您访问内部状态,我将为它声明属性。

所以,就像在其他语言中一样,我会将我的 ivars 隐藏在实现文件中,而不是在标题中声明它们。

在标题中声明 ivars 让我觉得非常奇怪。这些 ivars 是特定于实现的,不应该是头文件的一部分。

于 2012-10-09T09:05:51.157 回答