Objective-C is a great programming language, and has had support for declaring class properties via the @property
keyword.
Using a property provides accessor (getter and setter) methods in your class, without having to write them. It is very important to use accessor methods with object-oriented programming as it ensures encapsulation of data within a class. That means that there is no way for an outsider to modify class instance variables without using the getter/setter. As a programmer, you can implement these getter and setter methods in your class, allowing you control over the values that are stored in your class.
Previously in Objective-C, we were often writing both an @property
keyword in our interface (.h file), as well as a @synthesiz
e keyword in our implementation (.m file).
New in Xcode 4.4 (and the new LLVM clang compiler), we no longer need to synthesize our properties.
They are done for us when we compile our code!
Basics of properties
Let’s start with the basics of declaring class properties. We declare a property in our interface using the @property
keyword, followed by some attributes, the type and the name:
@property (attributes) type name
For example, let’s define an array called “posts” in our PostsController.h file:
@interface PostsController : UIViewController
@property (strong, nonatomic) NSArray *posts;
@end```objectivec
Normally, we would also synthesize the property in our implementation (.m file) as well:
```objectivec
@implementation PostsController
@synthesize posts = _posts;
@end
This would be equivalent to defining two methods in our class, one for accessing (getting) the posts array, and one for mutating (setting) the posts array from outside of our PostsController
object.
Best practices indicate that our getter method should be simply named after the property, in this case the method would be named “posts”, so one might call the method on an instance of our PostsController class like this: [postsController posts]
.
And, the setting method should be named setProperty:
.
In this case the method would be named “setPosts”, so one might call the method on an instance of our PostsController class like this: [postsController setPosts:newPosts]
.
Here is what the two methods would look like if we explicitly wrote the accessor methods ourselves.
@implementation PostsController {
NSArray *_posts;
}
-(NSArray *) posts {
return _posts;
}
-(void) setPosts: (NSArray *)posts {
_posts = posts;
}
@end
Synthesize by Default
Beginning with Xcode 4.4 (OS X 10.8 and iOS 5.1), we no longer need to use the @synthesize
keyword.
We simply declare the @property
in our interface, and Xcode takes care of the rest; creating the necessary instance variable as well as the accessor methods.
This is done when compiling our code using the new LLVM compiler (clang) when we do not explicitly define these ourselves.
We can still declare the accessor methods ourselves if we want to override this default behavior.
You do not have to do anything special in Xcode to make this happen.
Instance Variable Naming
Instance variables are now prefixed with the ”_” character, which you can still access within the class itself.
@interface PostsController : UIViewController
@property (strong, nonatomic) NSArray *posts;
@end
@implementation PostsController
/*Be default, the synthesis uses the "_"prefix
It would behave as if we had coded this: /*
@synthesize posts = _posts;
@end
Keep in mind, that if you write your own accessor methods (both getter and setter), then the instance variable is not created for you, and you have to define the instance variable yourself.
What if you have existing code that already defines the synthesis of the property, without the _prefix?
To preserve this backward compatibility, if you declare your @synthesize
property without defining an instance variable name, then it will continue to use that name (without the ”_” prefix).
For example, the following code would still work just fine.
@interface Person : NSObject
@property (strong, nonatomic) NSString *firstName;
@property (strong, nonatomic) NSString *lastName;
@end
@implementation Person
@synthesize firstName, lastName;
-(NSString *)fullname {
return [NSString stringWithFormat:@"%@ %@", firstName, lastName];
}
@end
You can read more about the declaring of properties in Xcode an Apple’s developer site. You can also read more about the new features of Xcode 4.4.