2009-06-13 39 views
1

有一些我试图理解。我在我的AppsController级的Cocoa应用程序Objective-C:对象声明问题

NSMutableArray *personArray; 

在此对象的声明可以放在头文件中或者类的代码文件里面执行这个声明。没什么区别。我甚至可以将它放在#import命令下的@implementation上下文中。应用程序工作正常。

由于我没有从AppsController类继承或做任何其他花哨的事情,我想知道这些类型的声明之间可能有什么区别?

声明真的属于哪里?

回答

7

这取决于你想如何使用变量。如果你把你的类接口里面的变量声明,你的类的每个实例都会有变量,它分开从你的类的所有其他实例其自己副本:

@interface AppsController : NSObject 
{ 
    NSMutableArray *personArray; 
} 

每个实例AppsController类将拥有自己的personArray变量的副本,它与该类的所有其他实例是分开的。

但是,如果你定义变量外设接口的,它成为一个全局变量,它是一个共享(你的类的实例没有得到他们自己的副本),并可以从访问你的班级的任何实例。如果您在头宣布它是这样:

NSMutableArray *personArray; 

它也是在其他文件和类,包括你的头的方法可见。

如果您在实现文件中声明变量,但在实现本身之外声明变量,并且将其作为static关键字的前缀,则该变量仅对类的实现可见。当你想要一个对所有类实例都可见的变量时,这是很常见的,但对其他人不可见,并且是创建类变量的一种方式。

由于您的对象是一个控制器对象,我猜测您的应用程序中只有一个它的实例。你应该声明变量之一:

  1. 作为一个实例变量,如果你的personArray变量需要独特到控制器类(每个实例,即使你只有一个实例现在,你可能有不止一个将来的实例)。
  2. 如果您希望变量对您的类的所有实例都可见,并且只有一个变量的共享实例,那么将其作为类变量(使用static关键字)。
  3. 如果您希望变量是单个实例(不是您的类的实例唯一),并且对其他类或其他文件中的代码也可见,则为全局变量。
4

你应该把它放在头文件的接口部分,这样每个对象将会有一个实例被实例化。我认为这是你的意图。

我想如果你把它放在别处它将被视为一个全局变量。也就是说,只会有一个personArray实例,并且它将在应用程序中的任何位置都可见。

您的应用程序可能正常工作,因为您只有一个AppsController类的实例,并且没有其他变量称为personArray。如果您需要第二个AppsController或另一个名为personArray的变量,则会遇到问题。

1

如果声明在执行文件中的变量,但实现本身之外,并用static关键字前缀它,变量将只在您的类的实现可见。当你想要一个对所有类实例都可见的变量时,这是很常见的,但对其他人不可见,并且是创建类变量的一种方式。

只是为了澄清,实现文件内,但实现部分外声明的原因变量是不可用的类之外​​,是因为其他类不知道的实现文件里的任何东西。您的导入语句引用了头文件,而不是它们的实现,所以他们对这些实现文件声明一无所知。

无论如何,要创建一个只能由类访问的静态变量,在执行文件中进行声明时使用关键字static。你可以把它放在文件的顶部,在实现部分的顶部,或者在一个函数中,这取决于你想要的范围。

编辑:纠正,不明确声明为`static`感谢彼得

+0

全局变量不是静态的,它们是外部的(C99§6.9.2¶4)。海湾合作委员会有一个编译器选项,通过使默认情况下符号具有隐藏的可见性,但它通常不会打开并且不是标准的,从而产生这种效果。 – 2009-12-03 08:48:41