Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 515 Vote(s) - 3.47 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Objective-C Static Class Level variables

#1
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.
Reply

#2
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).
Reply

#3
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.
Reply

#4
**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 Objective-C features

1. 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).

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

3. 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.)".

4. 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**:

1. [Class variables explained comparing Objective-C and C++ approaches][1]


[1]:

[To see links please register here]

Reply

#5
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.
Reply

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

#7
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.

Reply

#8
(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"`.
Reply

#9
Another possibility would be to have a little `NSNumber` subclass singleton.
Reply

#10
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](

[To see links please register here]

) 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.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through