19 May 2010

While cleaning up my code, I realized that I had gone hog-wild with @properties and @synthesize, so I was attempting to clean up un-necessary instances of them. What I found was that I could remove them all and my code would compile and run just fine. What are the circumstances when @property and @synthesize are mandatory?

1. Never

2. Whenever the property will be set in the format of “var = [[varitype alloc] init];”

3. Whenever the property will be read in the format of “anothervar = var;”

4. Whenever the properties attributes will be directly accessed as in “var.property = 2;”

Thanks.

JK

1 comment:

  1. This question has been bugging me too, so thanks for raising it, Jeff.

    First, I note that although the author uses @property to declare an interface element (like UILabel) to be an IBOutlet for InterfaceBuilder, this declaration can also be put directly in the @interface section:
    IBOutlet UILabel *label; will cause the label to appear immediately as an outlet in the Connections section of InterfaceBuilder's Inspector panel for the view controller that declares it. So this means that @property is really only necessary for assigning properties to the variable having to do with access (readOnly, nonatomic) and memory management (retain). At this point we have to take it on faith that it is useful or important to declare these properties, so that e.g. our code will run faster (nonatomic) and not have memory leaks or dangling pointers (retain).

    So this means, according to the literature, that we must also use @synthesize to automagically create the accessor methods for the variables. So what happens when you violate this principle -- e.g., in the .h file you say @property(nonatomic, retain) UILabel *label;
    and in the .m file you do label.text = @"HelloWorld";
    without first doing @synthesize label; ?

    Well, the first thing I notice is that I get a compiler warning: Property 'label' requires method -label to be defined - use @synthesize, @dynamic, or provide a method implementation. Ignoring such warnings usually a bad idea, but let's see what happens if we ignore it and try to run the code....

    As Jeff suggests, there are no obvious problems at runtime (for HelloWorld at least). However, when dealing with a language like Objective-C that requires you to manage memory for yourself -- and especially when running in an embedded environment like the iPhone -- it is inadvisable to ignore these sorts of warnings.

    In sum, it's a bad idea not to use @synthesize when you use @property, and it's a VERY bad idea not to use @property. The compile, run-time, or OS may compensate for your failure to declare properties, but until such automation becomes part of the language standard, there are no guarantees about what will happen.

    ReplyDelete