Objective C is a superset of the C programming language created by adding Smalltalk-style messaging support to C. Many programmers who come to Objective C without a good foundation of C don't have a good grasp of C pointers. When we write something like:
int i = 3;
i stores the value 3 at a position (address) somewhere in computer memory. This address is decided by the system and for clarity, we'll write it in hexadecimal. Let's say this address is 0x02. This means that if we look at the memory at location 0x02, we will see the value 3 stored in it.
int j = i;
The assignment operator copies the value of the right hand side to the left hand side. Thus,
j has the value 3 too. This value of
j (3) is stored in a different address – and let's say the address is 0x08 – than was used for storing the value of
i (also 3).
int* k = &i;
k is a pointer. And
&i refers to the address of
i (i.e. 0x02).
k's value is 0x02, since the assignment operator copies the value of the right hand side to the left hand side. i.e.
k's value is an address (0x02). And let's say
k's value itself is stored at address 0x12.
int m = *k;
*k is the syntax to read the value stored at the address represented by
k's value. Because 3 is the value stored in the address 0x02 (
m becomes 3. And let's say the value of
m is stored at the address 0x16.
So you can now recognize that as Objective C programmers, we have always dealt with pointers:
UIViewController* vc = [UIViewController new];
vc is a pointer to a` UIViewController instance.
Which is why after running this:
UIViewController* anotherVC = vc;
Both vc and anotherVC refers to the same
UIViewController. Because they are both pointers pointing to the same address which stores the
UIViewController instance (or "value").
Indirection is a useful technique for changing the value of objects directly by writing to its address. i.e. this code:
*k = 9;
Will change the value at the address (0x02) stored by k. Since 0x02 is the address used by
i, you will find that the value of
i has changed from 3 to 9.
There isn't a limit to the number of levels of indirection. i.e. you can have a pointer to a pointer to a pointer to an int (or float, etc), but it can get harder to reason. 2 level of indirection is fairly common though, for example,
NSFileManager has instance methods that uses this:
- (BOOL)createDirectoryAtPath:(NSString*)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(NSDictionary*)attributes error:(NSError**)error;
Notice that error is a pointer to a pointer to an
NSError instance. You use the API with code like this:
NSError* error; BOOL success = [[NSFileManager defaultManager] createDirectoryAtPath:somePath withIntermediateDirectories:YES attributes:nil error:&error]; //do something with error
This works because you pass in the address of error (with &error) – which is the address of the memory storing the address of the memory storing the value of
If you read about C, you might come across the terms "pass by value" and "pass by reference". Basically, pass by reference happens when you use pointers. Since you refer (hence reference) to the same value.