@property和@synthesize詳解
[toc]
在使用oc進行開發時,經常需要對大量的成員變數生成設值方法和取值方法,如果全部手動實現,那麼將浪費程式設計師大量的時間敲寫這些重複性的垃圾程式碼。自從oc2.0開始,可以自動生成設值和取值方法。那就是使用@property屬性和@synthesize關鍵字。關於這兩個關鍵字使用中的細節在這裡進行詳細的解釋。
1. 使用@property自動生成成員變數以及取值和設值方法
程式碼如下:
@interface Person:NSObject
@property int age;
@end
@implementation Person
@end
解釋:例如這種在實現部分不使用@synthesize,直接使用@property屬性進行宣告,那麼編譯器會自動生成一個int _age;
- (void)setAge:(int)age
{
_age = age;
}
- (int)age
{
return _age;
}
2. 手動實現設值方法,使用@property自動生成成員變數和取值方法
程式碼如下:
@interface Person:NSObject
@property int age;
- (void)setAge:(int)age;
@end
@implementation Person
- (void)setAge:(int)age
{
_age = age;
}
@end
解釋:例如這種在實現部分不使用@synthesize,直接使用@property屬性進行宣告,並且實現部分手動生成了設值setAge:方法,那麼編譯器會自動生成一個int _age;型的成員變數,而且會在實現部分自動生成如下的取值方法。
- (int)age
{
return _age;
}
同理,在實現部分不使用@synthesize,直接使用@property屬性進行宣告,並且實現部分手動生成了取值age:方法,那麼編譯器會自動生成一個int _age;型的成員變數,而且會在實現部分自動生成setAge:的設值方法。
3. 手動實現設值和取值方法,使用@property不會自動生成成員變數
程式碼如下:
@interface Person:NSObject
{
int _age; //此處必須手動實現
}
@property int age;
- (void)setAge:(int)age;
- (int)age;
@end
@implementation Person
- (void)setAge:(int)age
{
_age = age;
}
- (int)age
{
return _age;
}
@end
解釋:例如這種手動實現設值和取值方法,那麼即使使用了@property屬性,那麼編譯器也不會自動生成一個int _age;型的成員變數,必須自己手動宣告一個_age的成員變數。如果不手動宣告,那麼編譯器就會報錯,因為設值和取值方法找不到_age的成員變數。
4. @synthesize的使用
程式碼如下:
@interface Person:NSObject
{
int _age;
int age;
}
@property int age;
@end
@implementation Person
@synthesize age;
@end
解釋:
- 這種使用了@synthesize age;的情況,那麼設定和取值方法會預設訪問age成員變數,而不是_age成員變 量,如果沒有宣告age的成員變數,那麼設定和取值方法才會訪問_age的成員變數。
- 如果想讓設定和取值方法訪問_age的成員變數,那麼必須顯示指明,即使用@synthesize age=_age,這樣設定和取值方法就會訪問_age的成員變數,而不是age的成員變數。
- 例如@synthesize age=_age這種顯示指明訪問哪個成員變數的方式,如果沒有宣告_age的成員變數而聲明瞭age的成員變數,那麼編譯器也不會訪問age成員變數,編譯器而是會自動生成一個_age的成員變數去訪問。
總結
- @property和@synthesize提高了開發者的效率,不用重複的去敲寫垃圾程式碼。
- 在使用了@property的情況,若手動實現了設值方法,編譯會自動生成取值方法;若手動實現了取值方法,編譯會自動生成設定值法(若隻手動實現其中一個,編譯器還會自動生成相應的成員變數);若手動實現了設值和取值方法,編譯不會自動生成不存在的成員變數。
- @synthesize age=variablename,variablename決定了要訪問的成員變數。