Memory Management

Memory management is the act of managing computer memory. The basic idea behind this is to:

  1. Dynamically provide memory to an application when it is requested.
  2. Reserve that memory allocation while it is still in use.
  3. Free the memory when it is no longer needed, so that it can be reused.
1. is fairly straightforward. In fact, this is what you have been doing in your applications whenever you called alloc.

2. and 3. are the trickier aspects, and are notoriously a pain in most languages where memory management is performed manually.

Consider the following example.

We have two pointers to the same object, aView and theSameView.

Using memory management, we can deallocate the object.

This makes both pointers invalid, and the above app will crash when trying to use theSameView.

We can set the theSameView pointer to nil, but the app will still crash when trying to use aView, as that pointer is now referencing an invalid location.

At this point, you might be thinking that a good solution would be to never deallocate any objects. Unfortunately, that is a bad idea because there is a limit to the amount of total memory an app can use, and your app will crash if you ever reach it. Using up all available memory will also probably slow down your machine to a point where it’s unusable.

Reference Counting

How do you know when you’re done with your object? How do you know that your pointer is referencing an object that is still allocated?

One of the techniques is to use reference counting. This implies counting the number of pointers to an object in memory. Every time a pointer is added the counter increments. Every time a pointer is set to nil, the counter decrements. When the counter hits 0, it means that no pointers are referencing the object, and it can be safely deallocated.

As you can imagine, this process can get very tedious but luckily, many programming languages and compilers automate it.

The retain method increments the reference count, and release decrements it. In the above example, the object does not get deallocated when release is called on aView, because it still has a reference count of 1.

Automatic Reference Counting (ARC)

Before iOS 5, memory management had to be performed manually, but Automatic Reference Counting has been introduced in the later versions of the SDK.

This is an option that is set at the project level, and you’ve probably been using it for all the apps that you’ve built so far in the class.

ARC takes care of releasing and deallocating all the objects in memory that are not in use anymore. You simply need to set your pointers to nil when you’re done with them, and let the reference counter do its thing. You never need to call retain or release.

You can set the aView pointer to nil, but the theSameView pointer is still valid, as the object it points to still exists.

If you set both pointers to nil, then the reference count goes to 0 and the object is deallocated automatically.

Strong vs. Weak References

Modify the above example to use properties for your pointers.

This keeps the object in memory, as expected. What happens if we switch the reference type of theSameView to weak?

It’s not as bad as a crash, but the object referenced by theSameView has been deallocated, and theSameView now points to nil.

This happens because weak pointers are not counted by the reference counter. This is similar to using retain for strong pointers.

There are a few reasons why you would need weak pointers. Imagine you have a parent-child relationship between two classes where the parent has a pointer to its child and the child has a pointer to its parent. If you release the parent, you won’t be able to access it or its children anymore as you won’t have a pointer to reference it, but it will remain in memory because its children each have a pointer to their parent. This is called a retain cycle, and it can be avoided by using weak pointers from the children to their parent.

The general rule is that you want to use strong pointers to objects that you own, and weak pointers to objects that you borrow. This is why references to delegates tend to be weak, you’re just referencing those objects temporarily. Similarly for Storyboard outlets, which tend to be owned by their parent view, or by the base UIViewController class.

What about assign?

The assign directive is similar to weak except that it will not set the pointer value to nil when the referenced object is deallocated. It is conventionally not used for pointers, but for primitives (int, float, BOOL, etc.).

  1. Matthijs Hollemans. Beginning ARC in iOS 5 Tutorial Part 1., Nov 7 2011.

  2. Memory management. Wikipedia, Sep 25 2012.

  3. Reference counting. Wikipedia, Sep 1 2012.

Comments are closed.