One of the things I've been struggling with, whilst breaking into Objective-C programming, is understanding how to manipulate properties. I'm perhaps out of my comfort zone using a proper coding language as opposed to scripting languages that I'm used to, so the declaring things in header files and implementation files is confusing me somewhat.
Let's say I have a String. I wish to add some text into that string. What do I declare in the header file and what do I do in the implementation file to allow this to work properly, and what are @property and @synthesize?
In the bad old days before Objective-C 2.0, it was common to write getters and setters for your instance variables e.g.
@interface Foo : NSObject
{
@private
id foo;
}
-(void) setFoo: (id) newFoo;
-(id) foo;
@end
@implementation Foo
// need dealloc to release foo too.
-(void) setFoo: (id) newFoo
{
[newFoo retain];
[foo release];
foo = newFoo;
}
-(id) foo
{
return foo;
}
@end
And that's just in the single threaded environment. There was even more stuff needed for multithreaded apps.
Properties provide a neat shorthand for the above. The @property replaces both of the declarations in the interface as well as giving the caller better hints about the semantics of the getter and setter. It also allows you to @synthesize the accessors so the compiler will generate the code for them automatically (you don't have to @synthesize them, you can provide your own implementations if you want). All of the above can be replaced by
@interface Foo : NSObject
{
@private
id foo;
}
@property (nonatomic, retain) id foo;
@end
@implementation Foo
// need dealloc to release foo too.
@synthesize foo;
@end
That saves quite a lot of typing but also you can see from the interface that setFoo: will retain its new value and that the property is not safe to use (to set or get) in a multithreaded environment (without some other locking mechanism).