在@interface中声明ivar和在@implementation中放置变量之间的区别

时间:2011-04-06 00:47:44

标签: objective-c class scope variable-declaration

@interface中声明ivar与在.m文件中将变量放在@implementation之间有什么区别?

@interface MyClass : NSObject {
  int num;
}
- (void)doSomething;
@end

VS

@implementation MyClass   
int num2;

- (void)doSomething {
  num = 137;
  num2 = 138;
}
@end

有没有时间想要将变量放在@implementation

3 个答案:

答案 0 :(得分:8)

在实现中使用ivar和声明变量之间的区别在于实现中的变量位于文件范围和全局。这意味着所有实例(和任何静态方法)将共享同一个变量;即如果您的对象的一个​​实例更改了该变量,它将为所有实例更改它。

在文件范围定义它的用例是为静态方法存储内容(直接作用于类而不是类的实例的方法)。一个真正常见的用例是Singleton设计模式。您可以在此文件中定义类的静态实例,以便您可以随时确保访问同一实例。您可以提供一个返回此实例的静态方法,以便代码中的任何对象都可以通过直接在您的类上调用该方法来访问该对象。

2014年4月17日更新

现在的常见做法是使用Properties。这会为您创建getter和setter,自动使类更具可扩展性(如果您决定更改属性的工作方式,也许您希望将其更改为始终即时计算,则类的公共接口无需更改)。

您可以使用private class extensions to declare "private" properties and methods。这样可以保护某些属性和方法不被外部类访问。

答案 1 :(得分:5)

据我所知,在@implementation中放置一个变量声明与将它放在实现之外没有区别:它不是一个ivar,它只是在文件范围内声明的变量。

一个用途是声明C ++静态成员的等价物。例如:

@implementation MyClass

static int s_count = 0;

- (id)init {
  if ((self = [super init]))
    ++s_count;
  return self;
}

- (void)dealloc {
  --s_count;
  [super dealloc];
}

假设init是您唯一的初始值设定项,则s_count将包含有效的MyClass个实例总数。

答案 2 :(得分:1)

注意:从历史上看,接口需要声明类的实例变量,这些数据结构是类的每个实例的一部分。这些在@interface声明之后和方法声明之前在大括号中声明:

实例变量表示实现细节,通常不应在类本身之外访问。此外,您可以在实现块中声明它们或使用声明的属性合成它们。因此,通常不应在公共接口中声明实例变量,因此应省略大括号。

source