The way how variables are defined in Objective-C is very different to Java. Since Objective-C is dealing with pointers (see (NSString **) value) and developers have to be aware of memory management, the definition of variables is much more complicated and powerful than in Java.
1 – Java attributes
In this blog post I decided to start with the very basics based on Java.
We are deciding between two different kind of variables:
- instance variables
- class variables
1.1 – Instance variables
An instance variable is an attribute from a classes instance and exists for each instance. It will be initialized during the creation of the class instance. Instance variables can only be accessed by class instances and not by classes.
Instance variables are accessed like this:
SomeObject object = new SomeObject();
String value = object.value;
1.2 – Class variables
A class variable is an attribute of a class and exists exactly once by class and classloader. It will be initialized at class loading time and can be accessed by classes and class instances. All instances of a class will share this unique state of the variable. If you change the variable, it becomes changed for all instances of this class.
Class variables are accessed like this:
String value = SomeObject.value;
1.3 – Visibility Modifier
Java decides 4 different visibilities:
- public – visible for all objects
- protected – visible for all subclasses. Also visbile for classes in the same package
- private – only visible inside the class
- default – only visible for classes in the same package
1.4 – Final Modifier
The final modifier defines, that a variable has to be initialized once during the class loading or instance creation, but must never change.
1.4.1 – Final instance variable
Final instance variables are used for different behaviours. Eg to ease the handling of concurreny or to protect the state of a class.
1.4.2 – Final static variable
Final class variables are often used for constant definitions. “static final String” are very common to define constants.
2 – Objective-C attributes
In the second part of this post i am going to define the attributes defined above using Objective-C.
We are going to start with instance variables.
2.1 – Instance variables
Variables are defined in the .h interface file.
If you do not define something special, the attribute has visibility “protected”. You can use it in the .m implementation file and deal with it. Also subclasses of MyClass can access the attribute.
This image shows the attribute access in a subclass of MyClass.
See also: iphonedevelopertips.com, omnigroup.com
2.2 – Class variables
Differing to Java, Objective-C does not allow to use public / protected class variables. If variables are defined as static, they are allways private.
static NSString *anAttribute;
This variable can only be used inside of the class which defines this variable.
Another very confusing behaviour of static attributes is the fact, that they can be defined inside a method and will retain their value during subsequent calls. For instance the singleton pattern uses this very havily.
See stackoverflow.com for a similar example and a detailed description.
2.3 – Visibility Modifier
If the attribtue should be accessible from other classes, you have to use visibility modifiers.
Please not, that static attributes are always private.
For explanation i changed MyClass and added 3 attribtues with 3 different visibilities.
No i am trying to access them from
- MyClass.m – should work for all 3 attributes
- MySubClass.m – should work for protected and public
- OtherClass.m – should work for public
Everything is fine. No problems reported.
Private attributes can not be accessed by subclasses.
Since OtherClass is not a subclass of MyClass, only public attributes can be accessed. For sure, directly accessing public attributes from classes outside the typehierarchy is not good pratice! But for demonstration it is really well.
2.4 – Final modifier
As you could see, the visibility modifier has a very close semantic to java. But what is about the final modifier?
Actually, Objective-C does not provide a final modifier, but the keyword const (means constant).
But Const offers a much more complex semantic as final does. It allows pointers and / or values of pointers to be defined as “constant”.
“Final” only defines a constant reference which can not be changed, since java does not divide between reference and its value.
Lets compare the different possibilities:
private final Char someString;
The one and only way to define the char as final using java. Final means, that the value of the attribtue can only be assigned once. (During initilization)
It provides 3 different combinations of the const keyword.
// Pointer to constant char
const char* someString;
// Constant Pointer to char
char* const someString;
// Constant Pointer to constant char
const char* const someString;
We are going to use a few lines of code to get a feeling what i am talking about. The following image shows the three combinations of const mentioned above.
- Example 1 – “const char* charPtr1” means that the pointer charPtr1 is variable, but “the data the pointer is pointing to” is const. So only the “adress the pointer points to” can be changed. The “value the pointer is pointing to” is constant.
- Example 2 – “char* const charPtr2” means that the pointer charPtr2 is constant, but “the data the pointer is pointing to” is variable. So only the “value the pointer is pointing to” can be changed. The “adress of the pointer” is constant.
- Example 3 – “const char* const charPtr3” means that the pointer charPtr3 is constant, and “value the pointer is pointing to” is constant. Nor the “value or the adress” of the pointer can be changed.
How to define final variables using Objective-C?
I found a nice discussion about this issue: See iphonedevelopertips.com
Example 1 : final instance variable
public final String MY_STRING = "MyString";
extern const NSString* const MYSTRING;
const NSString* const MYSTRING = @"myValue";
Example 2 : final static variable
Since static attributes are always private, we do not have to specify anything in the header file. It is enough to specify the attribute in the implementation file.
public static final String MY_STRING = "MyString";
==> Nothing to do. static attribute is always private!
static const NSString* const MYSTRING = @"myValue";