Can Someone Explain This @Synthesize Syntax

Can someone explain this @synthesize syntax?

Only the first one (on the lhs of the synthesize statement) is synthesized with a getter and setter and becomes the "public" instance variable.

The latter (with the underscore) is still available inside the instance but is not exposed outside the instance. They both reference the same memory address.

When should I use @synthesize explicitly?

There's a lot of answers, but also a big confusion. I'll try to put some order (or increase the mess, we'll see...)

  1. Let's stop talking about Xcode. Xcode is an IDE. clang is a compiler. This feature we are discussing is called autosynthesis of properties and it's an Objective-C language extension supported by clang, which is the default compiler used by Xcode.

    Just to make it clear, if you switch to gcc in Xcode, you won't benefit from this feature (regardless from the Xcode version.) In the same way if you use a text editor and compile using clang from the command line, you will.

  2. Thank to autosynthesis you don't need to explicitly synthesize the property as it will be automatically synthesized by the compiler as

    @synthesize propertyName = _propertyName

    However, a few exceptions exist:

    • readwrite property with custom getter and setter

      when providing both a getter and setter custom implementation, the property won't be automatically synthesized

    • readonly property with custom getter

      when providing a custom getter implementation for a readonly property, this won't be automatically synthesized

    • @dynamic

      when using @dynamic propertyName, the property won't be automatically synthesized (pretty obvious, since @dynamic and @synthesize are mutually exclusive)

    • properties declared in a @protocol

      when conforming to a protocol, any property the protocol defines won't be automatically synthesized

    • properties declared in a category

      this is a case in which the @synthesize directive is not automatically inserted by the compiler, but this properties cannot be manually synthesized either. While categories can declare properties, they cannot be synthesized at all, since categories cannot create ivars. For the sake of completeness, I'll add that's it's still possible to fake the property synthesis using the Objective-C runtime.

    • overridden properties (new since clang-600.0.51, shipping with Xcode 6, thanks Marc Schlüpmann)

      when you override a property of a superclass, you must explicitly synthesize it

It's worth noting that synthesizing a property automatically synthesize the backing ivar, so if the property synthesis is missing, the ivar will be missing too, unless explicitly declared.

Except for the last three cases, the general philosophy is that whenever you manually specify all the information about a property (by implementing all the accessor methods or using @dynamic) the compiler will assume you want full control over the property and it will disable the autosynthesis on it.

Apart from the cases that are listed above, the only other use of an explicit @synthesize would be to specify a different ivar name. However conventions are important, so my advice is to always use the default naming.

What is this @synthesize statment doing?

In plain English, the @synthesize line says "Create the getter and setter methods for the property "ID", but don't use an instance variable called "ID" (the default) to store the value, use an instance variable called "_ID" instead."

Objective-C @synthesize syntax

This syntax is synthesizing the backing ivar for valueOne under the name _valueOne. You can simply write your code to look like

_valueOne.tag = 3;

That said, it's generally considered better to use the property accessors whenever possible, so you'd typically write this as

self.valueOne.tag = 3;

The notable exceptions to this are when you're in -init, -dealloc, or your own custom getter/setter you still want to use the ivar directly.


Using a prefixed underscore on ivar names is generally considered good practice, because it means if you write valueOne.tag = 3; and you meant to use the property, you get a compiler error instead of silently using the ivar. If you intend to use the ivar, you can just use the underscore prefix, as _valueOne.tag = 3;.

This is such a common practice that the auto-synthesis behavior of modern clang will use the leading-underscore style for ivars. This means that if you delete the @synthesize line entirely, it will behave as though you had @synthesize valueOne = _valueOne;.

Purpose of Synthesize

@synthesize in objective-c just implements property setters and getters:

- (void)setCoolWord:(NSString *)coolWord {
_coolWord = coolWord;
}

- (NSString *)coolWord {
return _coolWord;
}

It is true with Xcode 4 that this is implemented for you (iOS6 requires Xcode 4). Technically it implements @synthesize coolWord = _coolWord (_coolWord is the instance variable and coolWord is the property).

To access these properties use self.coolWord both for setting self.coolWord = @"YEAH!"; and getting NSLog(@"%@", self.coolWord);

Also note, both the setter and getter can still be manually implemented. If you implement BOTH the setter and getter though you NEED to also manually include @synthesize coolWord = _coolWord; (no idea why this is).

@property and @synthesize in objective-c

How complicated is it, really? It's just a bit of syntax that lets you specify the ivar that you want to use to back the property for which you're telling the compiler to create accessors. If they didn't provide this or something equivalent, then you'd always have to have your property names match your ivar names, and there are reasons that you might not want that.

If you don't need to name your ivars differently, then you don't have to bother with specifying the ivar name. In fact, you don't have to create ivars at all for your properties... if you don't, the compiler will create them for you.

Update: As of the middle of 2013, LLVM defaults to synthesizing accessors for properties, so in most cases you no longer need to specify @synthesize at all. The one case where you would still use it is when you want to back the property with a different instance variable than the one that the compiler would generate for you. Also, the default name for the ivar that backs a property will be the property name prefixed with an underscore. So, the code in the OP's example could be simplified by deleting the lines:

id _delegate;

and:

@synthesize delegate=_delegate;

I've removed my previous advice against using an underscore prefix since it clearly disagreed with the current fashion and default behavior of the compiler. As far as I know, it's still poor form to use an underscore prefix for your method names, however.

Also, it has come to my attention that at least one person interpreted the first line of my response, "How complicated is it, really?" as condescending. I hope that was only one person's impression -- I definitely didn't intend any condescension, but was only trying to frame my response around the OP's assertion that the @synthesize xxx=_xxx; directive makes things complicated. There's a lot to absorb when you're starting out; hopefully the new "synthesize by default" behavior will reduce the burden for newcomers.

What's the difference between @property and @synthesize?

You write @property in header file

@property float value;

is equivalent to:

- (float)value; 
- (void)setValue:(float)newValue;

It get information for OTHER classes, that your class has this methods

@synthesize phisicaly CREATE these methods in class implementation

What is the point of @property and @synthesize?

Objective-C Runtime Programming Guide: Declared Properties

@property declares the getter and the setter methods for the public property you want to implement. For example this property declaration:

@property float value;

is equivalent to:

- (float)value;
- (void)setValue:(float)newValue;

@synthesize provides default implementation for these two accessors.

Update: The above explains what these two do. It does not explain what their purpose is. :-)

  • @property adds a member to the public interface that acts as a data variable to your class clients, but is read and written using methods. This gives you better control over the data that is exchanged between the client and your code, for example you can do extended validation on the values your code is given.
  • @synthesize allows you to not explicitly write the code that will be called by the client and actually treat the property as a data variable yourself.


Related Topics



Leave a reply



Submit