Friday, December 24, 2010

Objective-C Immutable Example

With Objective-C there is no such thing as truly immutable example as you can always get at the memory and manipulate it (it's just pointers and memory after all). We had a goal of creating an immutable contract for Objective-C but still leverage the @property notation to minimize the memory management errors. The usecase is that in XCode any code type ahead would only show the read only accessors so that we know not to attempt to write to a property. But, internally in the class we can use the synthesized writeable accessors.

Here's an example of how we did it. First, define an interface in a usual manner, but set the properties to @property (readonly). Specify an initializer that takes all the methods.
#import <foundation/foundation.h>

@interface FooItem : NSObject

@property (nonatomic, retain, readonly) NSString* name;
@property (nonatomic, retain, readonly) NSNumber* count;
- (id) initWithValues:(NSString*) givenName withCount:(NSNumber*) givenCount; @end
Then in the implementation define a no name category that specifies the actual properties to be synthesized. These are done as readwrite so that the implementation itself has write accessors. In the initializer still continue to use the self accessors to have the benefits of runtime memory management.
#import "FooItem.h"

@interface FooItem ()

@property (nonatomic, retain, readwrite) NSString* name;
@property (nonatomic, retain, readwrite) NSNumber* count;

@end

@implementation FooItem

@synthesize name;
@synthesize count;

- (id) initWithValues:(NSString*) givenName withCount:(NSNumber*) givenCount {
    self = [super init];
    if (self) {
        self.name = givenName;
        self.count = givenCount;
    }
 
    return self;
}

- (void) dealloc {
    self.name = nil;
    self.count = nil;
 
    [super dealloc];
}

@end
Note, you could go to a true immutable implementation which would do a copy of the objects given in the initializer and specify copy on the @property. That seems an unnecessary amount of overhead for everyday use.

No comments:

Post a Comment