Site Search
Homepage of Otaku No Zoku
Complete Archives of Otaku No Zoku
About Otaku No Zoku
Subscribe to Otaku No Zoku
Bookmark Otaku No Zoku

Objective-C Class Properties :

Objective-C 2.0 offers some neat new features that make life easier for programmers. If you’re familiar with Java programming you are used to declaring getter and setter functions to access the instance variables of a class, and similarly in C#, you have the ability to declare property functions, get and set, which do the same thing, and have them be auto-implemented, i.e. you just have to let the compiler know you want a property accessor generated for a particular instance variable.

In Objective-C you can achieve the same task, i.e. implement automatic property getter and setter functions, using the new @property and @synthesize compiler directives, which are part of the Declared Properties feature, @property belonging to the Property Declaration Directives, and @synthesize being part of the Property Implementation Directives.

Wrapping your class instance variables, i.e. object’s properties in Objective-C, adheres to the principle of encapsulation of data which lets you exercise control over how particular properties can be interacted with, letting you range check passed in values, or perform secondary functions before assigning the new value.

Automatic Property Getter & Setter Implementation

The following example program adds Declared Properties, also known as property getter & setter functions, by using the appropriate compiler directives @property and @synthesize, to automatically generate functions to read and write the instance variables.

One of the property functions will treat the instance variable as read-only, using the readonly modifier attribute, meaning that within the class, direct access to the instance variable is via normal means, i.e. directly accessing the instance variable, and outside of the class the instance variable is read-only and its value cannot be altered. The other properties of the class use the readwrite modifier attribute to indicate that both getter and setter functions should be generated.

I use the notation of m_ on the instance variable names, a throwback to my days of C++ programming, to identify instance variables separately from their property accessor functions.

Steps

  1. Declare and implement a simple class that has a few sample values.
    1. Define a class that has four properties that need to be accessed outside of the class.
    2. Automatically implement a read-only property for the first property
    3. Automatically implement the property setter and getter for the other three properties.
  2. Define the main function.
    1. Create an instance of the sample class.
    2. Assign values to the properties via the automatically implemented getter & setter functions.
    3. Output the values of the class properties.

The Source Code

#import <Foundation/Foundation.h>

// declare the interface for the telepgrah message
@interface TelegraphMessage : NSObject
// add some instance variables that describe a standard telegraph message
NSString * m_operatorName;
NSString * m_message;
NSDate * m_date;
int m_cost;

// declare the automatically implemented property accessors
// the telegraph operators name can only be read by external code
@property(retain, readonly) NSString *operatorName;

// the message, date and cost can be read or written by external code
@property(copy, readwrite) NSString *message;
@property(retain, readwrite) NSDate *date;
@property(assign, readwrite) int cost;
@end

// define the implementation for the telegraph message
@implementation TelegraphMessage
// automatically generate the property accessors for each property
// name, connecting the property to the instance variable
@synthesize operatorName = m_operatorName;
@synthesize message = m_message;
@synthesize date = m_date;
@synthesize cost = m_cost;

// define the default constructor
- (id) init
{
    // hard-code the telepgraph operator's name, but this could easily
    // come from a database, or some other data source
    m_operatorName = @"Charlie";
    return self;
}
@end

int main (int argc, const char * argv[])
{
    // standard Foundation housekeeping
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	
    // define a telegraph message to send
    TelegraphMessage *telegraph = [TelegraphMessage new];
    telegraph.message = @"Hello World!";
    telegraph.date = [NSDate date];
    telegraph.cost = 10;

    // output the properties of the telepgrah message
    NSLog(@"Telegraph Operator: %@", telegraph.operatorName);
    NSLog(@"Telegraph Message: %@", telegraph.message);
    NSLog(@"Telegraph Date: %@", telegraph.date);
    NSLog(@"Telegraph Cost: %d", telegraph.cost);
    
    // standard Foundation housekeeping
    [pool drain];
    return 0;
}

Program Output

Telegraph Operator: Charlie
Telegraph Message: Hello World!
Telegraph Date: 2010-10-11 14:05:39 -0700
Telegraph Cost: 10

Results

The program output shows that the four instance variables are indeed accessed through the automatically implemented property accessors.

The first property, the telegraph operator’s name, which is read-only, is initialised during the class constructor to a default value which could easily be changed so that accessing the read-only property accessor could retrieve the operator’s name from a database or perform some calculation to decode the telegraph operator’s name by passing it through a super-secret cryptographic algorithm first.

The remaining three properties, message, date and cost, are all properties that can be read and written easily enough.

Summary

The ability to generate simplistic getter and setter functions, turning your instance variables in to properties, is a useful feature to have in any language. Anything that cuts down on verbose pages of code that do nothing very much, e.g. the functions of getPropertyX and setPropertyX that are frequently found scattered throughout Java classes.

There is still a need, in some cases, to hand-code a particular property accessor function based on the need to perform a calculation, or verify the values passed in before storing them, but most cases, automatically implementing the properties reduces code clutter and makes the intention of the original programmer clear to those programmers coming after them who now have to read the code and determine how something was intended to be used.

It’s always the little things about a particular programming language that cause the most frustration and so the ability to automatically generate class property getter and setter methods in Objective-C is a hugely useful feature that takes much of the drudgery out of declaring and exposing class variables.

Liked This Post?

Subscribe to the RSS feed or follow me on Twitter to stay up to date!