Cocoa Core Competencies

Object mutability

Most Cocoa objects are mutable—meaning you can change their encapsulated values—but some are immutable, and you cannot change their encapsulated values after they are created. The main benefit of immutable objects is the assurance that their values won’t change while you’re using them. Once you create an immutable object, the value it represents remains the same throughout its runtime life. But you can change the encapsulated value of a mutable object at any time. You can do this through methods that replace the values (“setter” accessor methods) or methods that incrementally modify them.

Object mutability is particularly important with the Foundation framework classes that represent collections and primitive data types. These classes have immutable and mutable variants, for example NSArray and NSMutableArray, or NSData and NSMutableData. The mutable class is a subclass of the immutable class and produces an object whose represented value or, in the case of collection classes, contained values can be changed.

Receiving Mutable Objects

When you call a method and receive an object in return, the object could be mutable even if the method’s return type characterizes it as immutable. There is nothing to prevent a class from declaring a method to return an immutable object but returning a mutable object in its implementation. Although you could use introspection to determine whether a received object is actually mutable or immutable, you shouldn’t. Always use the return type of an object to judge its mutability.

If you want to ensure that a supposedly immutable object received from a method does not mutate without your knowing about it, you can make snapshots of the object by copying it locally.

Storing Mutable Objects

When you design a subclass, a common decision is whether instance variables should be typed as the mutable or immutable variant of a given class. Generally, when you have an object whose contents change wholesale, it’s better to use an immutable object. Strings (NSString) and data objects (NSData) usually fall into this category. If an object is likely to change incrementally, it is a reasonable approach to make it mutable. Collections such as arrays and dictionaries fall into this category. However, the frequency of changes and the size of the collection should be factors in this decision. For example, if you have a small array that seldom changes, it’s better to make it immutable.