Declared property
A declared property provides a syntactical shorthand for declaring a class’s accessor methods and, optionally, implementing them. You can declare a property anywhere in the method declaration list, which is in the interface of a class, or in the declaration of a protocol or category. You use the following syntax:
@property (<#attributes#>) <#type#> <#name#>; |
You begin a property declaration with the keyword @property
. You can then optionally provide a parenthesized set of property attributes that define the storage semantics and other behaviors of the property. (Refer to the document that definitively describes property lists for descriptions of these attributes.)
Each property declaration ends with a type specification and a name. For example:
@property(copy) NSString *title; |
This syntax is equivalent to declaring the following accessor methods:
- (NSString *)title; |
- (void)setTitle:(NSString *)newTitle; |
In addition to declaring the accessor methods, you can instruct the compiler to synthesize implementations of them (or inform the compiler that your class will synthesize them at runtime).
You use the @synthesize
statement in a class’s implementation block to tell the compiler to create implementations that match the specification you gave in the property declaration.
@interface MyClass : NSObject |
{ |
NSString *title; |
} |
@property(copy) NSString *title; |
@end |
@implementation MyClass |
@synthesize title; |
@end |
You use the @dynamic
statement to tell the compiler to suppress a warning if it can’t find an implementation of accessor methods specified by an @property
declaration.
@implementation MyClass |
@dynamic title; |
@end |
Most Properties Are Backed by Instance Variables
By default, a readwrite
property will be backed by an instance variable, which will again be synthesized automatically by the compiler.
An instance variable is a variable that exists and holds its value for the life of the object. The memory used for instance variables is allocated when the object is first created (through alloc
), and freed when the object is deallocated.
Unless you specify otherwise, the synthesized instance variable has the same name as the property, but with an underscore prefix. For a property called firstName
, for example, the synthesized instance variable will be called _firstName
.
Although it’s best practice for an object to access its own properties using accessor methods or dot syntax, it’s possible to access the instance variable directly from any of the instance methods in a class implementation. The underscore prefix makes it clear that you’re accessing an instance variable rather than, for example, a local variable:
- (void)someMethod { |
NSString *myString = @"An interesting string"; |
_someString = myString; |
} |
In this example, it’s clear that myString
is a local variable and _someString
is an instance variable.
In general, you should use accessor methods or dot syntax for property access even if you’re accessing an object’s properties from within its own implementation, in which case you should use self
:
- (void)someMethod { |
NSString *myString = @"An interesting string"; |
self.someString = myString; |
// or |
[self setSomeString:myString]; |
} |
The exception to this rule is when writing initialization, deallocation or custom accessor methods, as described later in this section.
You Can Customize Synthesized Instance Variable Names
As mentioned earlier, the default behavior for a writeable property is to use an instance variable called _propertyName
.
If you wish to use a different name for the instance variable, you need to direct the compiler to synthesize the variable using the following syntax in your implementation:
@implementation YourClass |
@synthesize propertyName = instanceVariableName; |
... |
@end |
For example:
@synthesize firstName = ivar_firstName; |
In this case, the property will still be called firstName
, and be accessible through firstName
and setFirstName:
accessor methods or dot syntax, but it will be backed by an instance variable called ivar_firstName
.
Important: If you use @synthesize
without specifying an instance variable name, like this:
@synthesize firstName; |
In this example, the instance variable will also be called firstName
, without an underscore.
You Can Define Instance Variables without Properties
It’s best practice to use a property on an object any time you need to keep track of a value or another object.
If you do need to define your own instance variables without declaring a property, you can add them inside braces at the top of the class interface or implementation, like this:
@interface SomeClass : NSObject { |
NSString *_myNonPropertyInstanceVariable; |
} |
... |
@end |
@implementation SomeClass { |
NSString *_anotherCustomInstanceVariable; |
} |
... |
@end |
https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/DeclaredProperty.html#//apple_ref/doc/uid/TP40008195-CH13-SW1