tags:

views:

55

answers:

3

Hello. I'm new to Objective-C, but I am curious about something that I haven't really seen addressed anywhere else.

Could anyone tell me what is the difference between a private variable that is declared at the @interface block versus a variable that is declared within the @implementation block outside of the class methods, i.e:

@interface Someclass : NSObject {

 NSString *forExample;

}

@end

vs.

@implementation Someclass

 NSString *anotherExample;

-(void)methodsAndSuch {}

@end

It seems both variables ( forExample, anotherExample ) are equally accessible throughout the class and I can't really find a difference in their behaviour. Is the second form also called an instance variable?

+2  A: 

If you declare a variable inside the @implementation section, you're actually creating a global variable, visible everywhere (in every method in your application).

Member variables can only be declared in the @interface section. They are only accessible in the class itself.

Philippe Leybaert
+3  A: 

The latter is not defining an instance variable. Rather, it is defining a global variable in the .m file. Such a variable is not unique to or part of any object instance.

Such globals have their uses (roughly equivalent C++ static members; e.g. storing a singleton instance), but normally you would define them at the top of the file before the @implementation directive.

invariant
This is what I suspected and your answer makes perfect sense, but if I try to access `anotherExample` in any other class (by properly including `Someclass` in those classes) the compiler tells me that this variable is undeclared. What gives?
bitcruncher
@bitcruncher because `anotherExample` is only global to the .m file in which it was declared. If you want it available to other files, you'll have to declare `extern NSString * anotherExample;` in the .h file, then `#import` the .h file wherever you need the global. This reeks of a code smell, although it does have valid uses cases.
Dave DeLong
no actual code is smelling :-) this was just an exploratory question.
bitcruncher
+1  A: 

They're very different! The one in @implementation is a global variable not unique to each instance. Imagine there were accessors for both variables, written in the obvious way. Then the difference in behavior is shown here:

Someclass* firstObject = [[Someclass alloc] init];
Someclass* secondObject = [[Someclass alloc] init];

//forExample is an instance variable, and is unique to each instance.
[firstObject setForExample:@"One"];
[secondObject setForExample:@"Two"];
NSLog(@"%@",[firstObject forExample]); //Result: "One"
NSLog(@"%@",[secondObject forExample]); //Result: "Two"

//anotherExample is a global variable, and is NOT unique to each instance.
[firstObject setAnotherExample:@"One"];
[secondObject setAnotherExample:@"Two"];
NSLog(@"%@",[firstObject anotherExample]); //Result: "Two" (!)
NSLog(@"%@",[secondObject anotherExample]); //Result: "Two"

//Both instances return "Two" because there is only ONE variable this time.
//When secondObject set it, it replaced the value that firstObject set.

If you are looking for this sort of behavior, you might be better off using a class variable, like this:

static NSString* yetAnotherExample = nil;

Then you can use class methods to interact with the variable, and it's clearly class-specific (as opposed to instance-specific or global).

andyvn22
So would `anotherExample` be a program-wide global variable or a class global variable? In other words is `anotherExample` a global variable that exists _always_ or is it a global that exists when `Someclass` is instantiated?
bitcruncher
It exists *always*. You could declare `extern NSString* anotherExample` in another .m file and use it again. Please don't. But you could. :P
andyvn22
please don't think i actually code this way. :-) just trying to understand why others were doing this (doom for iphone, for example)
bitcruncher