Objective-C的屬性和成員變量用法及關係淺析

    在使用Objective-C語言進行了一段時間的iOS開發以後,發現本身的語言基礎相對薄弱,因而開始彌補本身的短處。我發如今用過一種語言以後,再回過頭來看它的不少原理會發現有更加深入的理解。下面就對一直困惑個人屬性和成員變量的用法和關係問題進行淺析,因爲水平有限可能會有錯誤,請看過文章的人多多指正。html

一、屬性編程

    關於屬性的用法在蘋果的官方文檔《The Objective-C Programming Language》中有詳細的說明,在這裏就再也不贅述,連接以下:app

    《The Objective-c Programming Language》編程語言

    若是你的英文很差,不要緊,已經有人把這個文檔所有翻譯完了,連接以下:函數

    Objective-C編程語言官方文檔翻譯ui

二、關於@synthesize object = _object 的解釋spa

    咱們在不少代碼中會見到這樣的寫法:.net

[plain] view plaincopy翻譯

  1. @interface MyClass:NSObject{    指針

  2.         MyObjecct *_object;  

  3. }  

  4. @property(nonamtic, retain) MyObjecct *object;  

  5. @end  

  6.   

  7. @implementatin MyClass  

  8. @synthesize object=_object;  

    我在網上查閱了一些和其餘人寫的博文,總結了這樣寫的幾條緣由以下:    

(1)32位系統和64位系統的差別

    在32位系統中,若是類的@interface部分沒有進行ivar(instance variable)聲明,但有@property聲明,在類的@implementation部分有響應的@synthesize,則會獲得相似下面的編譯錯誤:

    Synthesize property ‘xX’ must either be named the same as a compatible ivar or must explicitly name an ivar

    在64位系統中,運行時系統會自動給類添加ivar,添加的ivar以一個下劃線「_」作前綴。

(2)避免莫名其妙的Bug

    在這裏簡單說一下_object和object的區別。_object是MyClass類的成員變量,object是屬性。property和synthesize定義了一對getter和setter方法,在這裏的getter方法是object,setter方法是setObject,事實上getter和setter方法操做的是變量_object。

    若是寫synthesize objec = _object 時getter方法爲:

[plain] view plaincopy

  1. -(MyObject *)object  

  2. {  

  3.     return _object;  

  4. }  

    若是寫synthesize object 時getter方法爲:

[plain] view plaincopy

  1. -(MyObject *)object  

  2. {  

  3.     return object;  

  4. }  

    當函數名和屬性名重名的時候會出現意想不到的錯誤,爲了不這種Bug,Apple給的Demo Code裏面多數也採用這種方式。

(3)屬性和變量的用法

    屬性是用self.object,經過getter方法來調用的,能夠在類外使用。而變量是經過_object來調用,只能在該類對應的implementation中使用,在類外不能使用。

    下面看一下兩種賦值操做:

   

[plain] view plaincopy

  1. self.object = [[MyObject alloc] init];  

  2. object = [[MyObject alloc] init];  

    第一種的方式和@property(nonamtic,retain)有關,其實是經過調用setter方法setObject來實現賦值的。第二種方式是簡單的指針賦值,沒有調用setter方法。

    下面是retainCount的變化:

[plain] view plaincopy

  1. MyObject *tmp = [[MyObject alloc] init];  

  2. self.object = tmp;  //retainCount = 2  

  3. [tmp release];  //retainCount = 1  

  4. _object = [[MyObject alloc] init];  //retainCount = 1  

相關文章
相關標籤/搜索