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