[ACCEPTED]-Objective-C Static Class Level variables-static

Accepted answer
Score: 159

Issue Description:

  1. You want your ClassA to have a ClassB class variable.
  2. You are using Objective-C as programming language.
  3. Objective-C does not support class variables as C++ does.

One Alternative:

Simulate a class variable behavior using 18 Objective-C features

  1. Declare/Define an static 17 variable within the classA.m so it will 16 be only accessible for the classA methods 15 (and everything you put inside classA.m).

  2. Overwrite 14 the NSObject initialize class method to 13 initialize just once the static variable 12 with an instance of ClassB.

  3. You will be wondering, why 11 should I overwrite the NSObject initialize 10 method. Apple documentation about this method 9 has the answer: "The runtime sends 8 initialize to each class in a program exactly 7 one time just before the class, or any class 6 that inherits from it, is sent its first 5 message from within the program. (Thus the 4 method may never be invoked if the class 3 is not used.)".

  4. Feel free to use the 2 static variable within any ClassA class/instance 1 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:

  1. Class variables explained comparing Objective-C and C++ approaches
Score: 37

As of Xcode 8, you can define class properties 19 in Obj-C. This has been added to interoperate 18 with Swift's static properties.

Objective-C 17 now supports class properties, which interoperate 16 with Swift type properties. They are declared 15 as: @property (class) NSString *someStringProperty;. They 14 are never synthesized. (23891898)

Here is 13 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 12 is a very interesting explanatory post I used as a reference 11 to edit this old answer.


2011 Answer: (don't use this, it's 10 terrible)

If you really really don't want 9 to declare a global variable, there another 8 option, maybe not very orthodox :-), but 7 works... You can declare a "get&set" method 6 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 5 you need to get the value, just call:

NSString *testVal = [MyClass testHolder:nil]

And 4 then, when you want to set it:

[MyClass testHolder:testVal]

In the case 3 you want to be able to set this pseudo-static-var 2 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 1 handy methods:

+ (NSString*)test {
    return [MyClass testHolderSet:NO newValue:nil];
}

+ (void)setTest:(NSString*)_test {
    [MyClass testHolderSet:YES newValue:_test];
}

Hope it helps! Good luck.

Score: 29

On your .m file, you can declare a variable 5 as static:

static ClassName *variableName = nil;

Then you can initialize it on 4 your +(void)initialize method.

Please note that this is a 3 plain C static variable and is not static 2 in the sense Java or C# consider it, but 1 will yield similar results.

Score: 16

In your .m file, declare a file global variable:

static int currentID = 1;

then 7 in your init routine, refernce that:

- (id) init
{
    self = [super init];
    if (self != nil) {
        _myID = currentID++; // not thread safe
    }
    return self;
}

or if 6 it needs to change at some other time (eg 5 in your openConnection method), then increment 4 it there. Remember it is not thread safe 3 as is, you'll need to do syncronization 2 (or better yet, use an atomic add) if there 1 may be any threading issues.

Score: 11

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

Score: 3

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 3 will be the only method to access id, so 2 you will have to update it somehow in this 1 code.

Score: 2

(Strictly speaking not an answer to the 8 question, but in my experience likely to 7 be useful when looking for class variables)

A 6 class method can often play many of the 5 roles a class variable would in other languages 4 (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 3 object of class MyCls calls Resource:changeSomething: with the string 2 @"Something general" upon a call to doTheThing:, but an object derived 1 from MySpecialCase with the string @"Something specific".

Score: 0

u can rename the class as classA.mm and 1 add C++ features in it.

Score: 0

Another possibility would be to have a little 1 NSNumber subclass singleton.

More Related questions