self.property 與 _property 的區別

這篇文章分三段,先講@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)。通過屬性,可以用一行代碼來同時聲明存取方法

舉例:

  1. @property NSString *yhx;
  2. -(NSString *) yhx ;//供外部讀取實例變量的方法
    -(void) setYhx: (NSString *) yhx ;//供外部設置實例變量的方法

兩個作用是一樣的,都是在接口文件中聲明了存取方法。( 是這樣嗎?)


@synthesize

當在接口文件(.h文件)中聲明了@property后,在實現文件(.m文件)中,會自動合成存取方法,等效于自動幫你寫了以下這句,但是不會顯示給你看:

  @synthesize  yhx = _yhx ;//并不會顯示出來

在這里,我現在的理解是這樣的

  • yhx” 指的是存取方法的名字
  • _yhx” 是實例變量的名字(給實例變量命名時,習慣在最前面加一個下劃線

這里做的是

  • 先聲明一個名為 “_yhx” 的實例變量( 是這樣嗎? 嗯,應該是如此,見本文最后)
  • 再把名字為 “yhx” 的存取方法與名為 “_yhx” 的實例變量聯系了起來
  • “yhx”方法是用合適的步驟來讀取 “ _yhx” 這個實例變量的值

self.property 與 _property 的區別

那么

  1. self.yhx ; //通過@property自動生成的存取方法,或者自定義的存取方法來獲得yhx的值

  2. _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
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容