2013-01-01 115 views
1

我有幾個關於Objective-C中變量/對象聲明的問題,我希望你能幫助我更好地理解一些東西。Objective-C變量/對象聲明

  1. 我知道,給一個變量的@property聲明可以讓你從其他類訪問它,如果你不打算使用它,它自己在課堂之外,有沒有使用呢?

  2. 我經常在示例代碼中看到變量和對象只聲明使用@property而不是直接在@interface中聲明。爲什麼?

  3. 我還看到有人在使用@synthesize時,做了類似var = _var;的事情。怎麼來的?

  4. 當引用對象和變量時,是否有任何理由,例如做self.var.而不是var.

我認爲這就是所有,希望你能幫我解決這些奧祕(也許還有其他人),謝謝。

+0

MHM我怕你應該看看一個初學者的書(沒有進攻) - 這是一個有點廣闊對於這個網站的國際海事組織(這當然可能是錯的^^) –

+0

這主要是在這裏覆蓋:http://stackoverflow.com/q/843632/937822 – lnafziger

回答

3
  1. @property和合成,甚至私下使用,給你預構建 getter和setter。這就是我使用它們的原因。

  2. 在最近的Xcode中,您會得到一個爲您提供的合成,因此您 可以將@property與@synthesize單獨對待。

  3. 下劃線別名可以讓你的名字堆棧變量同樣沒有 歧義,e.g ....

    // say my class contains a property called foo, alias _foo. 
    - (void)initWithFoo:(id)foo { 
        self = [self init]; 
        if (self) { 
         _foo = foo; // assign the param to the instance var 
        } 
        return self; 
    } 
    
  4. 這是使用getter和setter的init和 的dealloc外面很好的做法。吸氣劑和吸附劑「夾斷」訪問 屬性到您可能想要添加行爲的單個位置。 例如,常見的做法是使用吸氣劑懶惰 初始化...

    // this code assumes ARC, otherwise for retained properties without arc, you'll need to add release and retain code here and if you replace the default setter 
    - (SomeType *)bar { 
        if (!_bar) { 
         _bar = [[SomeType alloc] init]; 
        } 
        return _bar; 
    } 
    
+1

「//分配給屬性的參數」是不是很正確 - 您將參數分配給實例變量。它不使用屬性設置器。此外,當不在ARC下時,它應該是'_foo = [foo retain]'或'_foo = [foo copy]',只是爲了讓任何人閱讀。 – Chuck

+0

謝謝,@Chuck - 我會編輯評論。還會指出我假設ARC。 – danh

1
  1. 當您使用@property是合成*你能避免書寫「樣板」的代碼,如複製或鎖定來訪問原子。隨着ARC的引入,這一功能的重要性大大降低。
  2. 無需在最新的Xcode中編寫@synthesize,您可以使用很少或不需要額外編碼的屬性。由於屬性比變量更「未來的證明」,因爲你可以在setter中執行驗證並在getter中執行計算,所以幾乎沒有理由使用「普通」變量。
  3. 在最新的Xcode中不需要使用@synthesize。如果您看到很多@synthesize,則可能是您正在閱讀「舊代碼」(超過6個月)。
  4. 不,沒有理由這樣做與變量。據說爲了清晰起見,一些商店要求程序員這樣做。我不會對此發表評論,因爲這是一個偏好問題。如果您決定這樣做,您應該在整個代碼庫中一致地執行此操作。
    *明確地通過@synthesize或隱式使用最新的Xcode。
2
  1. 您還可以訪問您不聲明爲屬性的變量。物業只是一條捷徑。一種告訴編譯器自動爲該變量創建getter和setter(accessor)方法的方法。您有時在括號中看到的標誌是更改訪問方法的實際實現的附加選項。
  2. 因爲在這種情況下,實例變量會在編譯時自動添加到您的類中。除了額外的下劃線前綴(_var)之外,該變量的名稱將與您的屬性相同。
  3. 這允許您更改自動生成的實例變量的名稱。等號後面是財產;實例變量在右側。你也可以自己聲明實例變量,如果它不同於屬性的名稱,你必須這樣分配它。
  4. 使用self.var將使用訪問器方法(無論它們是否自動添加,或者您自己實現它們)。例如,如果你想懶洋洋地加載一個對象,你可以實現一個getter自己來檢查,如果該對象已經存在,如果不創建它,並將其返回:

    // Assuming you defined @property (nonatomic) MyClass *var; in the header 
    - (MyClass *)var { 
        if (!_var) { 
         _var = [[MyClass alloc] init]; 
        } 
        return _var; 
    } 
    

    現在你可以使用點語法訪問:

    [self.var doSomething]; 
    

    這將調用上面定義的getter。如果變量是nil(尚未使用),則首先進行初始化。如果您剛剛使用實例變量...

    [_var doSomething]; 
    

    ...您將得到不同的結果。如果_varnil,則該消息將被忽略(無錯誤,崩潰)。這是因爲你直接訪問變量,而不是通過訪問器方法。當然,如果您確定該對象將被初始化,或者在nil時處理該案例,那麼您可以直接使用它。