< Previous PageNext Page > Hide TOC

Accessor Methods

This article describes why you should use accessor methods, and how you should declare and implement them.

Contents:

Accessor Method Fundamentals
Declaring Accessor Methods
Implementing Accessor Methods
Value Objects and Copying


Accessor Method Fundamentals

An accessor method is an instance method that gets or sets the state of an object. In Cocoa’s terminology, a method that retrieves an object’s state is referred to as a “get accessor” or “getter”; a method that changes the state of an object is referred to as a “set accessor” or “setter”. One of the principal reasons for using accessor methods is encapsulation (see “Encapsulation” in Object-Oriented Programming with Objective-C). In a reference counted environment, a particular benefit is that they can take care of most of the basic memory management for your classes.

Declaring Accessor Methods

You should typically use the Objective-C declared properties feature to declare accessor methods (see Declared Properties in The Objective-C 2.0 Programming Language), for example:

@property (copy) NSString *firstName;
@property (readonly) NSString *fullName;
@property (retain) NSDate *birthday;
@property NSInteger luckyNumber;

The declaration makes explicit the memory management semantics for the property.

Implementing Accessor Methods

In many cases you can (and should) avoid the need to implement your own accessor methods by using the Objective-C declared properties feature and asking the compiler to synthesize accessor methods for you:

@synthesize firstName;
@synthesize fullName;
@synthesize birthday;
@synthesize luckyNumber;

Even if you need to provide your own implementation, you should declare accessors using a declared property—you must ensure, of course, that your implementation meets the specification you give. (Note in particular that by default a declared property is atomic; if you don’t provide an atomic implementation, you should specify nonatomic in the declaration.)

For simple object values, there are, broadly speaking, three ways to implement the accessors:

  1. Getter retains and autoreleases the value before returning it; setter releases the old value and retains (or copies) the new value.

  2. Getter returns the value; setter autoreleases the old value and retains (or copies) the new value.

  3. Getter returns the value; setter releases the old value and retains (or copies) the new value.

Technique 1

In technique 1, values returned by the getter are autoreleased within the calling scope:

- (NSString*) title {
    return [[title retain] autorelease];
}
 
- (void) setTitle: (NSString*) newTitle {
    if (title != newTitle) {
        [title release];
        title = [newTitle retain]; // or copy depending on your needs
    }
}

As with values manufactured by class convenience methods, the returned object is autoreleased in the current scope and thus remains valid if the property value is changed. One issue with this technique is performance. If you expect your getter method to be called frequently, the added cost of retaining and autoreleasing the object may not be worth the performance cost.

Technique 2

Like technique 1, technique 2 also uses an autorelease technique, but this time does so in the setter method:

- (NSString*) title {
    return title;
}
 
- (void) setTitle: (NSString*) newTitle {
    [title autorelease];
    title = [newTitle retain];
}

The performance of technique 2 is significantly better than technique 1 in situations where the getter is called much more often than the setter.

Technique 3

Technique 3 avoids the use of autorelease altogether:

- (NSString*) title {
    return title;
}
 
- (void) setTitle: (NSString*) newTitle {
    if (newTitle != title) {
        [title release];
        title = [newtitle retain];
    }
}

The approach used by technique 3 is good for frequently called getter and setter methods. It is also good for objects that do not want to extend the lifetime of their values, such as collection classes.

Value Objects and Copying

It is common practice in Objective-C code to copy value objects—objects that represent attributes. C-type variables can usually be substituted for value objects, but value objects have the advantage of encapsulating convenient utilities for common manipulations. For example, NSString objects are used instead of character pointers because they encapsulate encoding and storage. Despite NSString functionality, the role played by NSString objects parallels the role played by character pointers.

When value objects are passed as method arguments or returned from a method, it is common to use a copy instead of the object itself. For example, consider the following method for assigning a string to an object’s name instance variable.

- (void)setName:(NSString *)aName {
    [name autorelease];
    name = [aName copy];
}

Storing a copy of aName has the effect of producing an object that is independent of the original, but has the same contents. Subsequent changes to the copy don’t affect the original, and changes to the original don’t affect the copy. Similarly, it is common to return a copy of an instance variable instead of the instance variable itself. For example, this method returns a copy of the name instance variable:

- (NSString *)name {
    return [[name copy] autorelease];
}


< Previous PageNext Page > Hide TOC


© 2009 Apple Inc. All Rights Reserved. (Last updated: 2009-05-06)


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.