這篇文章分三段,先講@property 以及 @synthesize ,然后到self.property 與 _property 的區別。
參考來自:《Objective-C編程》17.1存取方法 P103
《Objective-C 程序設計》第六版 10.2.1 關于屬性,存取方法和實例變量 P203
《Effective Objective-C 2.0》理解屬性這一概念 P21
@property
- 當類中的實例變量需要在外部被使用時,我們需要為這個實例變量編寫存取方法(因為面向對象的封裝性,外部不能直接訪問實例變量)。
- 需要被外部用到的實例變量可能有很多,于是Apple創建了一條便捷途徑,稱為屬性(property)。通過屬性,可以用一行代碼來同時聲明存取方法。
舉例:
- @property NSString *yhx;
- -(NSString *) yhx ;//供外部讀取實例變量的方法
-(void) setYhx: (NSString *) yhx ;//供外部設置實例變量的方法
兩個作用是一樣的,都是在接口文件中聲明了存取方法。( 是這樣嗎?)
@synthesize
當在接口文件(.h文件)中聲明了@property后,在實現文件(.m文件)中,會自動合成存取方法,等效于自動幫你寫了以下這句,但是不會顯示給你看:
@synthesize yhx = _yhx ;//并不會顯示出來
在這里,我現在的理解是這樣的
- “yhx” 指的是存取方法的名字
- “_yhx” 是實例變量的名字(給實例變量命名時,習慣在最前面加一個下劃線)
這里做的是
- 先聲明一個名為 “_yhx” 的實例變量( 是這樣嗎? 嗯,應該是如此,見本文最后)
- 再把名字為 “yhx” 的存取方法與名為 “_yhx” 的實例變量聯系了起來
- “yhx”方法是用合適的步驟來讀取 “ _yhx” 這個實例變量的值。
self.property 與 _property 的區別
那么
self.yhx ; //通過@property自動生成的存取方法,或者自定義的存取方法來獲得yhx的值
_yhx ; //直接訪問實例變量的值
兩者的區別在于,通過存取方法訪問比直接訪問多做了一些其他的事情(例如內存管理,復制值等)。
在斯坦福iOS7課程的課件中,是這樣說的:
直接訪問,應只用在存取方法以及初始化方法當中。
原文見補充內容。
我的理解是,因為在寫存取方法的時候,可能要自定義一些附加的任務,使得存取能夠符合自己的要求,比如
- @property (copy) NSString *yhx; 這里聲明了copy特性,所以存的時候就不是直接賦值了,而是先copy,再賦值。 (詳情可見《Effective Objective-C 2.0》中的第6條)
** P.S ** 當開發者自己把存和取,兩個方法都自己寫好了,那么
- 不會自動合成存取方法了
- 不能用“_yhx”直接訪問實例變量
- 需要自己把 @synthesize yhx = _yhx; 寫出來,才能用 “_yhx” 直接訪問實例變量
如果自定義了存或取方法,那么會自動合成另一個方法,也能用“_yhx”直接訪問實例變量。
補充內容
編譯器怎么處理@synthesize
以下內容參考于 iOS @synthesize var = _var 變量前置下劃線解釋
@synthesize age=_age;
下面是將被編譯的代碼:
@interface User : NSObject {
NSInteger _age;
}
@end
@implementation User
-(void)setAge:(NSInteger)newAge {
_age=newAge;
}
-(void)age {
return _age;
}
@end