4.2 Property Declaration and Implementation
There are two parts to a declared property, its declaration and its implementation
4.2.1 Property Declaration
A property declaration begins with the keyword @property, @property can appear in the method declaration list found in the @interface of a class, @property can also appear in the declaration of a protocol or category.
@property (attributes) type name;
// property only adds accessor to a instance variable,
// we still need to declare the instance variable
@interface MyClass : NSObject
{
float value;
}
@property float value;
@end
A property declaration equals to declaring two accessor methods.
@property float value;
// equals to
- (float) value;
- (vlid) setValue:(float) newValue;
4.2.2 Property Declaration Attributes
You can decorate a property with attributes by using the form @property(attribute1, attribute2, ...). For property declarations that use a comma delimited list of variable names, theproperty attributes apply to all of the named properties.
If you use @synthesize directive to tell the compiler to create accessor methods, the code will match the specification given by the keywords. If you implement the accessor methods, you should ensure it matches the specification.
1.Accessor Method Names
The default names for the getter and setter methods associated with a property arepropertyNameandsetPropertyName: respectively. The following attributes allow you to specify custom names instead:
getter = getterName
Specifies the name of the get accessor for the property. The getter must return a type matching the property's type and take no arguments.
setter = setterName
Specifies the name of the set accessor for the property. The setter method must take a single argument of a type matching the property's type and must return void.
If you specify that a property is readonly then also specify a setter withsetter=, you will get a compiler warning.
2. Writability
These attributes specify whether or not a property has an associated set accessor. They are mutually exclusive.
readwrite
indicates that the property should be treated as read/write. This is the default. Both a getter and setter will be required in the @implementation. If you use @synthesize in the implementation block, the getter and setter methods are synthesized.
readonly
indicates that the property is read-only.
3. Setter Semantics
assign
specifies that the setter uses simple assignment. This is the default
retain
specifies that retain should be invoked on the object upon assignment.
copy
specifies that a copy of the object should be used for assignment
@property and its attributes: http://stackoverflow.com/questions/2255861/property-and-retain-assign-copy-nonatomic :
1. assign: count will not increase
2. retain: count will increase
3. copy: create another object4. Atomicity ???
There is no keyword to denote atomic.
nonatomic
specifies that accessors are non-atomic. By default, accessors are atomic.
4.2.3 Property Implementation Directives
You can use @synthesize and @dynamic directives in @implementation blocks to trigger specific compiler actions.
The default value is @dynamic, If therefore, you do not specify either @synthesize or @dynamic for a particular property, you must provide a getter and setter method implementation for that property.
@synthesize
you use the @synthesize keyword to tell the compiler that it should synthesize the setter and/or getter methods for the propertyif you do not supply them within the @implementation block. (E.G. You can implement only setter and let the compiler implement the getter)
// Using @synthesize
@interface MyClass : NSObject
{
NSString @value;
}
@property(copy, readwrite) NSString *value;
@end
@implementation MyClass
@synthesize value;
@end
@dynamic
You use the @dynamic keyword to tell the compiler that you will fulfill the API contract implied by a property either by providing method implementations directly or at runtime.
4.3 Using Properties
4.3.2 Property Re-declaration
You can re-declare a property in a subclass, but(with exception of readonly vs. readwrite) you must repeat its attributes in whole in the subclass.
The ability to redeclare a read-only property as read/write enables two common implementation patters:
1. A mutable subclass of an immutable class (NSString, NSArray, and NSDictionary are all examples) ???
2. A property that has public API that is readonly but a private readwrite implementation internal to the class.
//public header file
@interface MyObject : NSObject
{
NSString *language;
}
@property (readonly, copy) NSString *language;
@end
//private implementation file
@interface MyObject {} // This is a class extension
@property (readwrite, copy) NSString *language;
@end
@implementation MyObject
@synthesize language;
@end
4.3.3 Copy
If you use the copy declaration attribute, you specify that a value is copied during assignment. If you synthesize the corresponding accessor, the synthesized method uses the copy method. In this way, your object will have its own privateimmutable copy.
// If you declare a property as follows:
@property (nonatomic, copy) NSString *string;
// The synthesized method is similar to the following:
- (void)setString: (NSString *)newString {
if (string != newString) {
[string release];
string = [newString copy];
}
}
The copy method will return an immutable version, so we should use
mutableCopy when necessary:
@interface MyClass : NSObject {
NSMutableArray *myArray;
}
@property (nonatomic, copy) NSMutableArray *myArray;
@end
@implementation MyClass
@synthesize myArray;
-(void) setMyArray: (NSMutableArray *) newArray {
if(myArray != newArray){
[myArray release];
myArray = [newArray mutableCopy];
}
}
@end
4.3.4 dealloc
Properties are not aut9omatically released for you.
But you can implement your dealloc method in this way: you can look for all the property declarations in your header file and make sure thatobject properties not marked assign are released and those marked assign are not released.
Note:
Typically in a dealloc method you should release object instance variables directly(rather than invoking a set accessor and passing nil as the parameter):
- (void)dealloc {
[property release];
[super dealloc];
}
If you are using the modern runtime and synthesizing the instance variable, However, you cannot access the instance variable directly, so you must invoke the accessor method:
- (void) dealloc {
[self setProperty:nil];
[super dealloc];
}
// [self setProperty:nil] equals to
[property release];
property = nil;
// 相当于C free之后将指针设为空
4.4 Subclassing with Properties
You can override a readonly property to make it writable:
@interface MyInterger : NSObject
{
NSInteger value;
}
@property(readonly) NSInteger value;
@end
@implementation MyInterger
@synthesize value;
@end
You can implement a subclass which redefines the property to make it writable:
@interface MyMutableInterger: MyInterger
@property(readwrite) NSInteger value;
@end
@implementation MyMutableInteger
@dynamic value;
// use the getter from super class
-(void)setValue: (NSInteger) newX {
value = newX;
}
@end
4.5 Performance and Threading
The declaration attributes that affect performance and threading are retain, assign, copy, and nonatomic.
retain/copy/assign affect only the implementation of the assignment part of the set method:
// assign
property = newValue;
// retain
if(property != newValue) {
[property release];
property = [newValue retain];
}
//copy
if(property != newValue ) {
[property release];
property = [newValue copy];
}
Atomic left...
Property vs Instance Variable
It makes it easier to get access to the instance variable.
http://stackoverflow.com/questions/719788/property-vs-instance-variable
Run time difference P 68.