I have a class Film, each of which stores a unique ID. In C#, Java etc I can define a static int currentID and each time i set the ID i can increase the currentID and the change occurs at the class level not object level. Can this be done in Objective-C? I've found it very hard to find an answer for this.
9 Answers
Issue Description:
- You want your ClassA to have a ClassB class variable.
- You are using Objective-C as programming language.
- Objective-C does not support class variables as C++ does.
One Alternative:
Simulate a class variable behavior using Objective-C features
Declare/Define an static variable within the classA.m so it will be only accessible for the classA methods (and everything you put inside classA.m).
Overwrite the NSObject initialize class method to initialize just once the static variable with an instance of ClassB.
You will be wondering, why should I overwrite the NSObject initialize method. Apple documentation about this method has the answer: "The runtime sends initialize to each class in a program exactly one time just before the class, or any class that inherits from it, is sent its first message from within the program. (Thus the method may never be invoked if the class is not used.)".
Feel free to use the static variable within any ClassA class/instance method.
Code sample:
file: classA.m
static ClassB *classVariableName = nil;
@implementation ClassA
...
+(void) initialize
{
if (! classVariableName)
classVariableName = [[ClassB alloc] init];
}
+(void) classMethodName
{
[classVariableName doSomething];
}
-(void) instanceMethodName
{
[classVariableName doSomething];
}
...
@end
References:
-
3Can you have a static variable of Type ClassA within classA.m? – goatlinks Jan 08 '10 at 07:52
-
6this might be a silly question but what about the release of said memory? doesn't matter because it has to live as longs a the app is running? – samiq Jan 20 '11 at 20:10
-
1@samiq, check out [Objective-C: Why retain a static variable?](http://stackoverflow.com/questions/6316723/objective-c-why-retain-a-static-variable). The pointer to the object cannot be deleted, but the object itself can. You probably don't want to release it because you most likely want it around for as long as the app is running, but you will save memory if you release it, so if you know you don't need it anymore, then you should release it. – ma11hew28 Jun 12 '11 at 14:01
-
5If initialize() is guaranteed to be called only once, why do you need the conditional "if (! classVariableName)"? – j b Jun 28 '11 at 09:27
-
So you can't initialize it again. :) – Trevor Jul 04 '11 at 14:27
-
23@jamie, `initialize` is called once for each class (superclasses before subclasses), but if a subclass does not override `initialize`, the parent class `initialize` will get called again. Hence, a guard is required if you don't want that code executing twice. See [Initializing a Class Object](https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocObjectsClasses.html#//apple_ref/doc/uid/TP30001163-CH11-87244) in Apple's Objective-C docs. – big_m Oct 03 '11 at 16:02
-
I use `+(void)load`, not `initialize`, which is called once per category or class... and not superclasses. – nielsbot Mar 05 '12 at 08:50
-
@big_m thats a good point, since the link mentioned in the comment is invalid now, I have mentioned the check condition that needs to be added inside the `+initialize` method. `if(self == [ClassA class]) { //do initialisation }` – user1046037 Jan 23 '13 at 09:01
-
1The benefit of using a static class varable is that each instance does need to retain a copy of the same data. The static is in memory created only once with all class instances referencing it. Albaregar's solution does not reap this benefit. Without statics I believe Objective C is a flawed OO implementation. – Andrew S Feb 08 '13 at 18:10
-
When using ARC just be careful to nullify your static variable when you don't need it anymore in contrary ARC will not release memory for that object and will never call dealoc method to cleanup memory for that object. Static in ARC is not a weak reference. – Voda Ion Apr 09 '14 at 13:59
-
do you think this answer has been superceded by @gonzalo's answer below? – rustyMagnet Mar 14 '19 at 09:51
As of Xcode 8, you can define class properties in Obj-C. This has been added to interoperate with Swift's static properties.
Objective-C now supports class properties, which interoperate with Swift type properties. They are declared as: @property (class) NSString *someStringProperty;. They are never synthesized. (23891898)
Here is an example
@interface YourClass : NSObject
@property (class, nonatomic, assign) NSInteger currentId;
@end
@implementation YourClass
static NSInteger _currentId = 0;
+ (NSInteger)currentId {
return _currentId;
}
+ (void)setCurrentId:(NSInteger)newValue {
_currentId = newValue;
}
@end
Then you can access it like this:
YourClass.currentId = 1;
val = YourClass.currentId;
Here is a very interesting explanatory post I used as a reference to edit this old answer.
2011 Answer: (don't use this, it's terrible)
If you really really don't want to declare a global variable, there another option, maybe not very orthodox :-), but works... You can declare a "get&set" method like this, with an static variable inside:
+ (NSString*)testHolder:(NSString*)_test {
static NSString *test;
if(_test != nil) {
if(test != nil)
[test release];
test = [_test retain];
}
// if(test == nil)
// test = @"Initialize the var here if you need to";
return test;
}
So, if you need to get the value, just call:
NSString *testVal = [MyClass testHolder:nil]
And then, when you want to set it:
[MyClass testHolder:testVal]
In the case you want to be able to set this pseudo-static-var to nil, you can declare testHolder
as this:
+ (NSString*)testHolderSet:(BOOL)shouldSet newValue:(NSString*)_test {
static NSString *test;
if(shouldSet) {
if(test != nil)
[test release];
test = [_test retain];
}
return test;
}
And two handy methods:
+ (NSString*)test {
return [MyClass testHolderSet:NO newValue:nil];
}
+ (void)setTest:(NSString*)_test {
[MyClass testHolderSet:YES newValue:_test];
}
Hope it helps! Good luck.

- 3,523
- 25
- 30
-
Cool, but it's not really a global variable because it cannot be accessed from other `.m` files, and I think it's fine for it to be "global" within the `Class.m` file. – ma11hew28 Jun 12 '11 at 13:18
On your .m file, you can declare a variable as static:
static ClassName *variableName = nil;
Then you can initialize it on your +(void)initialize
method.
Please note that this is a plain C static variable and is not static in the sense Java or C# consider it, but will yield similar results.
In your .m file, declare a file global variable:
static int currentID = 1;
then in your init routine, refernce that:
- (id) init
{
self = [super init];
if (self != nil) {
_myID = currentID++; // not thread safe
}
return self;
}
or if it needs to change at some other time (eg in your openConnection method), then increment it there. Remember it is not thread safe as is, you'll need to do syncronization (or better yet, use an atomic add) if there may be any threading issues.

- 17,664
- 2
- 43
- 56
As pgb said, there are no "class variables," only "instance variables." The objective-c way of doing class variables is a static global variable inside the .m file of the class. The "static" ensures that the variable can not be used outside of that file (i.e. it can't be extern).

- 23,305
- 6
- 62
- 80
Here would be an option:
+(int)getId{
static int id;
//Do anything you need to update the ID here
return id;
}
Note that this method will be the only method to access id, so you will have to update it somehow in this code.

- 31
- 2
(Strictly speaking not an answer to the question, but in my experience likely to be useful when looking for class variables)
A class method can often play many of the roles a class variable would in other languages (e.g. changed configuration during tests):
@interface MyCls: NSObject
+ (NSString*)theNameThing;
- (void)doTheThing;
@end
@implementation
+ (NSString*)theNameThing { return @"Something general"; }
- (void)doTheThing {
[SomeResource changeSomething:[self.class theNameThing]];
}
@end
@interface MySpecialCase: MyCls
@end
@implementation
+ (NSString*)theNameThing { return @"Something specific"; }
@end
Now, an object of class MyCls
calls Resource:changeSomething:
with the string @"Something general"
upon a call to doTheThing:
, but an object derived from MySpecialCase
with the string @"Something specific"
.

- 6,363
- 1
- 36
- 46
Another possibility would be to have a little NSNumber
subclass singleton.

- 31,030
- 13
- 103
- 118