Brian Love
Angular + TypeScript Developer in Denver, CO

Synthesize by Default with Xcode 4.4

Reading time ~3 minutes

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 @synthesize 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


Normally, we would also synthesize the property in our implementation (.m file) as well:

@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.

Brian Love

Hi, I'm Brian. I am interested in TypeScript, Angular and Node.js. I'm married to my best friend Bonnie, I live in Denver and I ski (a lot).