Issue of lazy loading property
I’ve got some
readonly properties in my .h file. And when I tried to lazy loading them as usual like this.
Then…bang! It threw out errors in bulk, yelling “Use of undeclared identifier ‘_imageView’”. What the hell have I done!
Luckily, I found some explainations here. It says:
Newer Xcode versions can create a
@synthesizestatement automatically and use the underscore prefix for instance variables. In this case however, since the property is read-only and you provide a getter method, Xcode does not synthesize the property automatically.
So, I have to
@synthesize the property on my own, and now it’s quiet and cute again. :P
I happened to recall this issue when clearing up the whole system of Objective-C. Let’s dig deeper about this issue and find if there’s a diamond in it. :P
This issue has references of two points:
@synthesize. Let’s dig more details one by one.
I’d love to reference this paragraph of Ry’s Objective-C Tutorial to show the goal of @property in Objective-C.
An object’s properties let other objects inspect or change its state. But, in a well-designed object-oriented program, it’s not possible to directly access the internal state of an object. Instead, accessor methods (getters and setters) are used as an abstraction for interacting with the object’s underlying data.
The goal of the @property directive is to make it easy to create and configure properties by automatically generating these accessor methods. It allows you to specify the behavior of a public property on a semantic level, and it takes care of the implementation details for you.
First of all, this feature is called autosynthesis of properties and it’s an Objective-C language extension supported by clang, which is the default compiler used by Xcode.
Thanks to autosynthesis you don’t need to explicitly synthesize the property as it will be automatically synthesized by the compiler as
@synthesize propertyName = _propertyName.
While, there’re some exceptions here:
- Readwrite property with custom getter and setter;
- Readonly property with custom getter;
- @dynamic (which is opposited to
- Properites declared in a @protocol;
- Properties declared in a category;
- Overriden properties.
In this condition, property
name is set to be
readwrite(as it is by default) with custom getter and setter. At this time, compiler believes that you want to take full control over
@property manually, and then forbids autosynthesis for you.
—Note— atomic property’s accessor type must be paired, either custom or autosynthesis. Or else, there would be a warning like this.
We’ve already been used to not defining ivars on our own, once you have to use ivar, while autosynthesis is invalid, you’ll have to use
@synthesize to compound ivars(i.e. let out the comment for line 24 in the image above).
Here’s a little sample.
Output in console:
It’s also fine to get subclass’s ivar
name simply by
This is cited from this article, under the heading “Methods provided at runtime”.
Some accessors are created dynamically at runtime, such as certain ones used in CoreData’s NSManagedObject class. If you want to declare and use properties for these cases, but want to avoid warnings about methods missing at compile time, you can use the
@dynamicdirective instead of
@dynamicdirective essentially tells the compiler “don’t worry about it, a method is on the way.” :]