6

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

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

对比

@implementation MyClass   
int num2;

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

有没有时候你想把一个变量放在@implementation?

4

3 回答 3

8

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

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

2014 年 4 月 17 日更新

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

您可以使用私有类扩展来声明“私有”属性和方法。这具有保护某些属性和方法不被外部类访问的效果。

于 2011-04-06T01:06:42.637 回答
4

据我所知,将变量声明放在 @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

于 2011-04-06T01:01:19.030 回答
1

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

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

来源

于 2012-08-05T01:52:49.993 回答