【问题标题】:Difference between declaring an ivar in @interface and putting variable in @implementation在 @interface 中声明 ivar 和在 @implementation 中放入变量之间的区别
【发布时间】:2011-07-30 10:32:23
【问题描述】:

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

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

对比

@implementation MyClass   
int num2;

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

您是否曾经想在@implementation 中放置一个变量?

【问题讨论】:

    标签: objective-c class scope variable-declaration


    【解决方案1】:

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

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

    2014 年 4 月 17 日更新

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

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

    【讨论】:

    【解决方案2】:

    据我所知,将变量声明放在 @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 实例的总数。

    【讨论】:

    • 即静态全局变量可以作为类变量。
    • 我只是在和一些人谈论它,他们说 ivar 是一个实例变量,而在 @implementation 中声明的变量是“全局的,而不是每个实例”。对我来说,这听起来像是静态的。我知道 ivar 是什么,但仍不清楚 @implementation 中的变量以及何时应该使用它。
    • @nickfox 全局变量,无论是否静态,都与程序具有相同的生命周期,并且可以被实现文件中的任何方法或函数使用,这就是为什么它们可以用作类变量。 非静态全局变量也可以被其他实现文件使用,类似于公共类变量。 静态全局变量只能由声明它的实现文件使用,因此充当私有类变量。
    【解决方案3】:

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

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

    (source)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-18
      • 2012-02-09
      • 1970-01-01
      • 2011-01-10
      • 2014-09-23
      • 1970-01-01
      • 2015-07-29
      • 1970-01-01
      相关资源
      最近更新 更多