Objective-C static const variables - objective-c

I am trying to create a class with static const variables that can be used from outside the class, but I cannot figure out how to initialize this variable.
Example Code:
#interface ExampleClass
{
static const int CONST_VAR;
}
- (id) init;
#end
#implementation ExampleClass
- (id) init {
CONST_VAR = 1;
}
#end
I want to be able to reference the static constant variable like this:
ExampleClass.CONST_VAR;

You should assign a value to this static variable by doing the following:
-(id)init{
ExampleClass.CONST_VAR = 1;
}
Because this is a static variable or "class variable", you must use the class name in any case regardless of where you are this includes from inside the same class.
Hope this helps.

Related

Static attribute, Static Class, Singleton Pattern

I have 3 class.
Class A contains :
A static variable "dataX".
A setter method to set the data.
A getter method to return the data value.
Class B
Class C.
the flow is as follows:
The Class B instanciates the Class A and initialize the variable "dataX" with the setter method.
Afterwards, the class C instantiates the Class A in the viewDidLoad method and gets the value of the static variable.
But even if the variable in Class A is static, the variable is always null.
I guess that I need to put the Singleton Pattern with a static Class A and not simply a static attribute.
What is the syntax to specify a Class as Static?
The code below:
// HandleMessage.h
#interface HandleMessage : NSObject
#property *NSString nameFile;
// Getter
- (NSString *)getNameFile;
// Setter
- (void)setNameFile: (NSString *) value;
#end
And:
// HandleMessage.m
#import "HandleMessage.h"
#implementation HandleMessage
static nameFile;
#synthesize nameFile ;
// Getter definition
- (NSString *)getNameFile{
return nameFile;
}
// Setter definition
- (void)setNameFile: (NSString *) value{
nameFile = value;
}
When you instantiate another instance of a class of course this instance's value is null.
You can work with singletons or store your data elsewhere (if you want to keep data between app starts in your user defaults using NSUserdefaults)
what do you mean by "Class as Static"??
you can use singleton pattern, which i described in this answer
or using class method
ClassA.h
#interface ClassA
+ (void)setData:(int)data;
+ (int)getData;
#end
ClassA.m
static int sData;
#implementation ClassA
+ (void)setData:(int)data {
sData = data;
}
+ (int)getData {
return data;
}
#end

Passing static object between two class in objective c [duplicate]

This question already has answers here:
Objective-C Static Class Level variables
(9 answers)
Closed 8 years ago.
Does someone know how to pass static object in objective c ?
In java its something like :
class A {
static int x;
...
}
class B {
...
A.x = 4;
}
something alike.
Someone know how to achieve the same result using Objective C NSString ?
thanks.
In Objective-C, there are no class (static) variables. One thing you can do is to use global variables, but that's generally discouraged:
// A.h
extern int x;
// A.m
int x;
// B.m
#import "A.h"
x = 4;
However, you should instead rethink your code design, you should be able to get away without using globals.
You'll have to declare your variable on the top of your .m and create a getter and setter for the static variable and work with that
static int x;
+ (int)getX {
return x;
}
+ (void)setX:(int)newX {
x = newX;
}
Objective-C doesn't have static/class variables (note that the difference between static and class methods is subtle but significant).
Instead you can create accessors on the class object and use a global static to store the value:
#interface MyClass : NSObject
+(NSString *)thing;
+(void)setThing:(NSString *)aThing;
#end
#implementation MyClass
//static ivars can be placed inside the #implementation or outside it.
static NSString *_class_thing = nil;
+(void)setThing:(NSString *)aThing {
_class_thing = [aThing copy];
}
+(NSString *)thing {
return _class_thing;
}
//...
#end
There is no direct way to do in Obj-C.
You need to create a class-method, that will access the static property.
// class.h
#interface Foo {
}
+(NSString *) string;
// class.m
+(NSString *) string
{
static NSString *string = nil;
if (string == nil)
{
// do your stuff
}
return string;
}

program doesn't remember value/can't return value (XCode)

Hi I have a little a problem. My program doesn't remember random value which is generated by clicking first button. But I want use that value in another button and there is the problem. If I try to return that value, program says that this methond shouldn't return value. Here's how my code looks like:
int randomprocess;
- (IBAction)button:(id)sender {
randomprocess = rand() % 3;
// Do something }
- (IBAction)b1:(id)sender {
if (randomprocess == 0) {
// Do something
} else {
// Do something else
}
If I won't write that very first line, the second button won't recognize 'randomprocess'. And now when I declare it it's still zero or whatever number I set it to equal.
Probably, you have declared an iVar / property with the very same name, that covers your global variable. Use only a global variable or an iVar.
An declaration int randomprocess; outside a method or object head makes it to a 'normal' global C variable.
An iVar is a local variable in relation to your object. An property is (usually) an iVar with certain accessors.
If you have declared both, a global variable and a local one (resp, an iVar), the global one is not visible, but covered by the local one.
In general it is a bad idea to use global variables. If you have to, make it static. Better is to use an iVar.
EDIT
To make an property, your header should look like:
#interface myclass
#property (nonatomic,assign) int randomprocess;
// ...
#end
And for the implementation:
#implementation myclass
#synthesize randomprocess; // only for XCode < 4.4 needed
// ...
- (IBAction)button:(id)sender {
self.randomprocess = rand() % 3;
// Do something
}
- (IBAction)b1:(id)sender {
if (self.randomprocess == 0) {
// Do something
} else {
// Do something else
}
//
}
Or you should just declare your variable like this
#interface myclass {
int randomprocess;
}
inside .h file or :
#implementation myclass {
int randomprocess;
}
inside .m file
This will declare internal variable (iVar) without property
If you will do this inside .m file (2nd sample) this variable will available only in current file
If you will do this inside .h file (1st sample) this variable will be available for current .m and in subclasses as well

Issue understanding "Referring to Instance Variables" from Apple guide

I am trying to understand Referring to Instance Variables from Apple guide but having issue understudying this, Apple Doc says
...When the instance variable belongs to an object that’s not the receiver, the object’s type must be made explicit to the compiler through static typing. In referring to the instance variable of a statically typed object, the structure pointer operator (->) is used.
Suppose, for example, that the Sibling class declares a statically typed object, twin, as an instance variable:
#interface Sibling : NSObject
{
Sibling *twin;
int gender;
struct features *appearance;
}
As long as the instance variables of the statically typed object are within the scope of the class (as they are here because twin is typed to the same class), a Sibling method can set them directly:
- makeIdenticalTwin
{
if ( !twin )
{
twin = [[Sibling alloc] init];
twin->gender = gender;
twin->appearance = appearance;
}
return twin;
}
Referring to instance variable means, accessing the class instance vars
For example:
#interface ClassA : NSObject
{
int value;
}
- (void) setValue:(int) val;
#implementation ClassA
- (void) setValue:(int) val
{
//here you could access class a value variable like this
value = val;
}
Now accessing other classes variables
take for example this class
#interface ClassB : ClassA
{
ClassA aClass;
}
- (void) setValueInAClass:(int) val;
#implementation ClassB
- (void) setValueInAClass:(int) val
{
//class b could access variables from class a like this
aClass->value = val;
}
Please note that this is very un recommended to do, using the "->" breaks the encapsulation of class a, so dont in 99% of the cases referring to class variables using the "->" is a mistake

Objective-C Static Class Level variables

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.
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:
Class variables explained comparing Objective-C and C++ approaches
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.
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.
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).
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.
(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".
u can rename the class as classA.mm and add C++ features in it.
Another possibility would be to have a little NSNumber subclass singleton.