How to Write Accessor Methods for iOS Apps

By Rajiv Ramnath

To make instance variables available outside their defining class in a controlled manner, the best practice in iOS app development is to write accessor methods (also called getters and setters). Properties provide a declarative way to do so through use of the property directives @property and @synthesize.

By using a declarative style, you make your program do something without writing any code. Code is written, but by the compiler (that automatically generates the accessor methods), not by you.

An example of a property from the StackOfInteger class follows next. The idea is to allow a user of this class to read the stack pointer without exposing the last variable and without writing any new methods.

To begin, the property must be declared in the interface of the StackOfInteger class. The following snippet shows how to do so using the @property compiler directive:

@interface StackOfInteger:NSObject
{
 @protected // This is the default
 NSMutableArray* elements;
 @private int last;
}
 @property (readonly, atomic) int stackPointer;
 … other StackOfInteger methods
–d

Note that, even though the term property appears to be closer in meaning to a variable than to a method, the property definition goes in the section where methods are defined, not where the instance variables are defined. Note also that this property has two attributes: atomic and readonly.

To be clear, atomic means that safe concurrent access is provided and readonly means that this property can be read but not modified.

Next, you need to synthesize the property using the @synthesize directive, which means that either a new instance variable must be generated for the property or an existing instance variable must be linked to it. Here’s how you generate a new instance variable named the same as the stackPointer property:

@synthesize stackPointer;

In this example, the stackPointer property is linked to the instance variable last. The synthesize directive looks like this:

@synthesize stackPointer=last;

The property is now ready to use.

You can use the property two ways, as shown in the main function of the example:

  • You can use an accessor method:

    printf("Count of elements %dn", [myStack stackPointer]);
  • Or you can use dot notation to do the same thing, as shown here:

    printf("Count of elements using dot notation %dn",
      myStack.stackPointer);

The so-called dot notation is just shorthand for a method call. Rather than using the square braces, [instance method] for example, simply write instance.method.

Note that the names of the accessor (getters and setters) follow a naming convention. The getter method is the name of the property. So, for the property stackPointer, the getter method is also stackPointer. The setter method is the name of the property in camel case prefixed by the string set — the name of the setter method for stackPointer is setStackPointer.

Use camel case spelling (an uppercase letter in the middle of a term) when spelling these methods. Therefore, the S in the word stack is uppercase in the name of the setter method, even though it’s not capitalized in the name of the property. Note that the setter method is not generated for this property because it is read-only.

It’s time to move on to the attributes of properties. They’re all in the following list along with what they do:

  • nonatomic: By default, the accessor methods generated for properties include locking to make them safe for concurrent access by multithreaded programs. Specifically, the default behavior is atomic. If you use the attribute nonatomic, no locking is used.

    There isn’t an attribute named atomic (atomic operation is assumed by the lack of the nonatomic attribute).

  • readwrite: If you use this property, it can be written to as well as read. Both a getter and a setter are made available upon synthesis.

  • readonly: The compiler makes only a getter available.