14

Ok, still re-adjusting to things when switching between C, C++, C# and Objective-C so sometimes my head spins. This time however, I'm more confused as to the proper way since I have seen at least three different ways to declare static variables in Objective-C, and there's a fourth if you consider it's just a superset of C itself. So which of these is right?

Additional Question

If we want to share a stand-alone variable (i.e. not a static class variable, but one just defined in a header) is that done the same way as in 'C' (ala with 'extern' in the header?)


Option A

Foo.h

@interface Foo : NSObject{
    static int Laa;
}

@end

Foo.m

@implementation Foo
    ...
@end

Option B

Foo.h

@interface Foo : NSObject{
}

@end

Foo.m

static int Laa; // <-- Outside of the implementation

@implementation Foo
    ...
@end

Option C

Foo.h

@interface Foo : NSObject{
}

@end

Foo.m

int Laa; // <-- Note no word 'static' here like in 'Option B'

@implementation Foo
    ...
@end

Option D

Foo.h

static int Laa;

@interface Foo : NSObject{
}

@end

Foo.m

@implementation Foo
    ...
@end

Option E

Foo.h

@interface Foo : NSObject{
}

@end

Foo.m

@implementation Foo

    static int Laa;

    ...

@end

Bonus question...

Do you have to use the word extern or is that only when you are using .c/.c++ files, not .m/.mm files?

Mark A. Donohoe
  • 28,442
  • 25
  • 137
  • 286

3 Answers3

16

The Option A is wrong. Objective -c class doesn't have a static variable.

Option B and E are the correct way to implement static variables.

Option C creates a global variable that might be accessed out side the implementation file using extern keyword.

Option D again creates a global static variable which can be accessed from anywhere by just importing .h file.

About your bonus question: extern keyword has the same meaning as in C/C++.

Mark A. Donohoe
  • 28,442
  • 25
  • 137
  • 286
Inder Kumar Rathore
  • 39,458
  • 17
  • 135
  • 184
  • So option D would be the equivalent of using extern then, correct? – Mark A. Donohoe Feb 14 '12 at 17:17
  • I actually came here to know which one of B and E is the canonical method, but +1 anyway because the other answers are missing the point of the question. I can't find a definite reference, but the convention does seem to be preferring Option E (even the XCode sample projects seem to do it that way). – Manav Sep 10 '12 at 10:22
  • 1
    @Manav Yeah the apple sample uses the E option and as far as I remember E & B doesn't have any difference. If you come up with a difference, that would be a great thing that I would love to know. – Inder Kumar Rathore Sep 10 '12 at 14:52
3

It depends on what you mean by "static". Objective-C gets the static keyword from C, so it has nothing to do with classes. If you're trying to make a class variable like you would in C++, then the Objective-C equivalent is just a global inside the .m file. If you use the static keyword when declaring the global, it ensures that the variable can't be extern'd and used in other files, which is probably what you're after.

Tom Dalling
  • 23,305
  • 6
  • 62
  • 80
  • So taking classes out of the equation altogether for a moment, you're saying if in the .m file I just declare `int foo;` I can extern it in the .h file just like in C. However, if I declare it as `static int foo;`, again in the .m file, it's otherwise exactly the same but can't be externed? Pt 2: What about declaring the variable (with or without the static word) inside the @implementation, ala option E above? Didn't think that was possible but that was the answer on another question here. – Mark A. Donohoe Feb 14 '12 at 06:01
  • 1
    Yes, globals can be `extern`'d by default, but making the global static will disable that. As for the second point, declaring the global inside the `@implementation` block doesn't affect it at all. It's still just a normal global. – Tom Dalling Feb 14 '12 at 06:23
0

Since you provided multiple choice, I'd have to go with Option A. This is for a static variable only visible within the class. For access to it externally, you'd write a custom getter and setter method similar to this answer.

Community
  • 1
  • 1
Tim
  • 14,447
  • 6
  • 40
  • 63
  • 1
    Correct me if I'm wrong, but isn't a property an instance-specific thing, not a class-level static, meaning you'd have to have an instance of the class that exposes the internal static? – Mark A. Donohoe Feb 14 '12 at 05:24
  • This will works similarly: http://stackoverflow.com/questions/695980/how-do-i-declare-class-level-properties-in-objective-c You simply manually write the set / get methods yourself instead of using @synthesize. – Tim Feb 14 '12 at 05:28
  • You are correct. You can just make the methods your self though. See hereL http://stackoverflow.com/questions/695980/how-do-i-declare-class-level-properties-in-objective-c – MGA Feb 14 '12 at 05:29
  • Edited my answer - I'm not a frequent user of static variables. – Tim Feb 14 '12 at 05:29
  • Haha, hivemind: answered with the same link within 30 seconds of each other. – Tim Feb 14 '12 at 05:33
  • Ok, that answers the Class-level statics, but how about just plain-old statics that are unrelated to a class? In plain-C we'd define the variable twice... once in the header, with the 'extern' prefix, then in one of the 'c' files where we'd actually set its value. Do we do the same thing for Objective-C since it is just a superset? – Mark A. Donohoe Feb 14 '12 at 05:41
  • Unrelated to the class? I'm not sure what you mean. If you declare it inside the Interface as in option A, it's available to the class as if it were a global (no using `this` or `self`). – Tim Feb 14 '12 at 05:43
  • And @Tim, in example A, the static is declared in the variables area for the class in the header file, but the article you linked to declared it inside the implementation of the static (+) method in the implementation file. Are they roughly the same (the difference being the former is a protected-level where the latter is scoped only to the method? – Mark A. Donohoe Feb 14 '12 at 05:43
  • Unrelated to the class as in a free-standing variable, which is sort of like a non-class-scoped static. My fault for mixing up words. I'll clarify my question. – Mark A. Donohoe Feb 14 '12 at 05:45
  • And is there a pragmatic difference between A and B? The only one I can think of is B is similar to A if A were defined as Private, not Protected. – Mark A. Donohoe Feb 14 '12 at 05:49