There are two aspects to properties: the syntactic elements used to declare properties, and the syntactic elements used to access properties. This section gives a brief overview of both, and discusses the motivation behind the feature.
Motivation
Declaring Properties
Accessing Properties
You typically access instance variables through a pair of accessor (getter/setter) methods. You can think of state managed through this accessor style API as being the properties of an instance of the class. By using accessor methods, you adhere to the principle of encapsulation (see “Mechanisms Of Abstraction” in Object-Oriented Programming with Objective-C > The Object Model). You can exercise tight control of the behavior of the getter/setter pair and the underlying state management while clients of the API remain insulated from the implementation changes.
Although using accessor methods therefore has significant advantages, writing accessor methods is nevertheless a tedious process—particularly if you have to write code to support both garbage collected and managed memory environments. Moreover, aspects of the property that may be important to consumers of the API are left obscured—such as whether the accessor methods are thread-safe or whether new values are copied when set.
The Objective-C declared properties feature offers the following advantages:
The property declaration provides a clear, explicit specification of how the accessor methods behave.
The compiler can synthesize accessor methods for you, according to the specification you provide in the declaration. This means you have less code to write and maintain.
Properties are represented syntactically as identifiers and are scoped, so the compiler can detect use of undeclared properties.
Runtime introspection of the properties declared by a class.
The declaration of a property is, effectively, a shorthand for declaring the setter and getter for an attribute of an instance of a class, although it also provides a specification for the accessors’ behavior. In addition to the declaration itself, there are implementation directives to instruct the compiler to synthesize the accessors and to inform the compiler that you will provide the methods yourself at runtime.
You use the compiler directive @property to declare a property. It can appear anywhere in the method declaration section of a class, category, or protocol declaration.
You use the @synthesize and @dynamic directives in @implementation blocks to trigger specific compiler actions: @synthesize instructs the compiler to synthesize the relevant accessors; @dynamic informs the compiler that you will provide the methods yourself at runtime.
Listing 4-1 illustrates the declaration of a property, value, and use of the @synthesize directive to instruct the compiler to create accessor methods to match the specification given in the declaration.
Listing 4-1 Declaring properties in a class
@interface MyClass : NSObject |
{ |
NSString *value; |
} |
@property(copy, readwrite) NSString *value; |
@end |
@implementation MyClass |
@synthesize value; |
@end |
Using the dot syntax, you can access a property using the same pattern as accessing structure elements.
MyClass *myInstance = [[MyClass alloc] init]; |
myInstance.value = @"New value"; |
NSLog(@"myInstance value: %@", myInstance.value); |
The dot syntax is purely “syntactic sugar”—it is transformed by the compiler into invocation of accessor methods (so you are not actually accessing an instance variable directly). The code example above is exactly equivalent to the following:
MyClass *myInstance = [[MyClass alloc] init]; |
[myInstance setValue:@"New value"]; |
NSLog(@"myInstance value: %@", [myInstance value]); |
Last updated: 2008-02-05