views:

422

answers:

3

Hello

there is something I try to understand. I have this object declaration in my AppsController-Class for a Cocoa Application

NSMutableArray *personArray;

In can put this declaration inside the Header file or inside the implementation of the class in the code file. It makes no difference. I can even put it outside the @implementation context right under the #import commands.The Application works just fine.

Since I don't inherit from the AppsController Class or do anything else fancy with it I wonder what might be the difference between these types of declarations?

Where does the declaration really belong?

+4  A: 

You should probably put it in the interface section of the header file, that way there will be one instance of it per object instantiated. Which I presume is your intention.

I think if you put it elsewhere it will be treated as a global variable. Ie, there will only ever be one instance of personArray, and it will be visible from anywhere in your application.

Your application is probably working fine, because you only have one instance of your AppsController Class, and no other variables called personArray. If you ever need a second AppsController, or another variable elsewhere called personArray, you'll run into problems.

Tom
+6  A: 

It depends on how you want to use the variable. If you place the variable declaration inside the interface for your class, each instance of your class will have its own copy of the variable, which is kept separate from all other instances of your class:

@interface AppsController : NSObject
{
    NSMutableArray *personArray;
}

Each instance of the AppsController class will have its own copy of the personArray variable, which is separate from all other instances of the class.

If, however, you define the variable outside of the interface, it becomes a global variable, and it is a shared (instances of your class do not get their own copy), and can be accessed from any instance of your class. If you declare it in the header as such:

NSMutableArray *personArray;

it is also visible to methods in other files and classes that include your header.

If you declare the variable in the implementation file, but outside of the implementation itself, and prefix it with the static keyword, the variable will only be visible to the implementation of your class. This is common when you want a variable that is visible to you all of class instances, but not visible to anyone else, and is a way to create class variables.

Since your object is a controller object, I am guessing that you only have one instance of it present in your application. You should declare the variable either:

  1. As an instance variable if your personArray variable needs to be unique to each instance of your controller class (even if you only have one instance now, you may have more than one instance of it in future).
  2. As a class variable (using the static keyword) if you want the variable to be visible to all instances of your class, with only one, shared instance of the variable.
  3. As a global variable if you want the variable to be a single instance (not unique to instances of your class) and also visible to other classes or code in other files.
Perspx
+1  A: 

If you declare the variable in the implementation file, but outside of the implementation itself, and prefix it with the static keyword, the variable will only be visible to the implementation of your class. This is common when you want a variable that is visible to you all of class instances, but not visible to anyone else, and is a way to create class variables.

just to clarify, the reason variables declared inside the implementation file but outside the implementation section are not available outside the class, is because other classes are not aware of anything inside the implementation file. your import statements refer to headers, not their implementations, so they know nothing of those implementation file declarations.

anyway, to create a static variable accessible only by a class, use keyword static when making a declaration in an implementation file. you can put it at the top of the file, at the top of the implementation section, or inside a function, depending on what you want the scope to be.

edited: corrected, thanks peter

ozmo
Global variables not explicitly declared as `static` are not static, they're external (C99 §6.9.2 ¶4). GCC has a compiler option that gives that effect, by making symbols have hidden visibility by default, but it's not normally on and it's not standard.
Peter Hosey