Often a property needs to be publicly read only but privately it needs to be read/write. The Objective-C 2.0 @property syntax does not provide a means to do this, but it is possible to do so without resorting to accessing ivar directly by canny use of categories. Here’s how:
@interface Person : NSObject
{
}
-(void)eatChocolateCake;
@end
@interface Person (ReadOnlyProperties) //the category name is arbitrary, but it cannot be anonymous
@property(readonly, nonatomic) NSString *mood;
@end
@interface Person () //this category should be anonymous so it is coalesced with the base @interface declaration
@property(readwrite, nonatomic, retain) NSString *mood;
@end
@implementation Person
@synthesize mood = mood_;
-(id)init
{
self = [super init];
if (self)
{
mood_ = @"hungry";
}
return self;
}
-(void)dealloc
{
[mood_ release];
[super dealloc];
}
-(void)eatChocolateCake
{
self.mood = @"happy";
}
@end
Person *frank = [[Person new] autorelease];
NSLog(@"Frank is feeling %@", frank.mood); //Frank is feeling hungry
[frank eatChocolateCake];
NSLog(@"Frank is feeling %@", frank.mood); //Frank is feeling happy
//frank.mood = @"sleepy"; //this line causes a compiler error
NSLog(@"Frank is feeling %@", frank.mood); //Frank is feeling happy