簡體   English   中英

在Objective-C中,何時應該使用屬性,何時應該使用實例變量?

[英]In Objective-C, when should I use property and when should I use instance variable?

我不熟悉具有屬性和實例變量的程序語言。
所以我不知道使用屬性和實例變量的好方法。

現在我只使用Objective-C代碼中的屬性,並且我不使用任何實例變量。

我需要使用實例變量嗎?
或僅使用屬性是Objective-C的最佳實踐?

@interface ViewController : UIViewController
{
    // instance variable
    @public
    int a;
}

// property
@property(nonatomic, strong) NSString *b;

@end

變量和屬性之間的基本區別在於,您可以為屬性賦予屬性。 您不能將任何屬性賦予變量。 所以,如果你希望有任何特定的行為,比如保留變量,以原子方式訪問它,可以訪問類,那么你應該選擇屬性。

如果您只是想在類中訪問變量,並且沒有特殊行為附加到該變量,則無需通過屬性訪問它。 您可以直接使用變量本身。 它也將改善性能。

@property比ivar有一些優點:

  • 內存管理 :在幕后,它將創建一個setter,用於創建具有正確內存管理的變量。 它會為您節省一些麻煩,因為您可以輕松地查看內存管理是如何完成的( strong / weakretain / copy / assign )。

  • 來自其他類的可訪問性 :如果您在.h中聲明了@property ,並且在.m中對它進行了@synthesize那么您的ivar將是公共可讀和可寫的。 您可以使用privat類擴展來阻止此操作。 你甚至可以聲明一個@property public readonly並通過privat類擴展在內部聲明readwrite 例如:私人財產

   // [In the implementation file]  
   @interface MyClass ()  
   @property (nonatomic, retain) NSMutableArray* someData; // private!!   
   @end  

   @implementation MyClass @synthesize someData   
   @end
  • 自定義getter和setter :如果你喜歡,你仍然可以編寫自定義getter和setter,你甚至可以只寫一個getter或setter,讓另一個自動@synthesize 您可以將自定義邏輯編寫到這樣的getter和setter中,例如,您可以在@property更改后重新加載tableview。

  • 符合自動鍵值觀察(KVO) :如果您使用或計划使用KVO,您只需通過聲明屬性即可免費獲得。 沒有其他事情需要做!

  • 點表示法 :如果你有@property你可以通過點表示法訪問getter和setter。

   self.myIvar = (id) someThing; 
   [array addObject:self.myIvar];
  • 如果你需要你iVar公開,寫一個@property比為iVar寫一個getter和setter更簡單

  • 隨着@property你不需要在伊娃聲明(在iOS和64位Mac OS X的應用程序)。 你可以通過@synthesize來做到這一點:

    @synthesize myiVar = _myIvar;

到處使用屬性。 甚至不要聲明實例變量,而是像這樣合成它們: @synthesize myProperty = _myProperty ,以便將它們與屬性名稱區分開來。 屬性也是處理內存管理的好方法。 您必須使用合成實例變量的唯一位置是dealloc方法。
這些屬性的優點很多:
- 訪問器方法定義了如何獲取和設置實例變量的值。
- 您可以自定義訪問器方法(例如,延遲實例化ivar或在設置新值(如setNeedsDisplay時執行某些操作。
- 設置新值時,您無法處理內存管理 - 設置器負責釋放/保留(取決於您如何聲明屬性 - retain / copy / assign / strong
- 一些具有atomic / nonatomic屬性的多線程東西
- 使用屬性時,您可以利用KVO
- 至少,但不是最后 - 如果您每次調用吸氣劑或定位器時都不關心性能問題,請不要擔心......

@property是一個實例變量,它已經應用了一些語義糖,以幫助將它暴露給外部世界(通常),並幫助避免編寫樣板代碼來獲取和設置它。

雖然屬性通常在你需要訪問類之外的某個變量時產生,但是在目標C中,另外需要make屬性是內存管理在編譯器端進行,所以如果你正在使用某個對象,不是原始數據類型,那么你應該使用屬性並合成它,然后如果你使用手動引用計數,則在dealloc中釋放。 但同樣主要的目標是使它能夠訪問類外的一些iVar,比如將參數從一個類傳遞給其他類等。

如果@synthesize @property ,您將可以訪問get和set方法,這非常方便。 您還可以定義setter的行為(保留,賦值,復制),如果它是非原子的或原子的,並且它是只讀的。 如果你沒有指定任何東西(也就是說你沒有合成屬性),那么默認情況下,ivar在類之外是不可見的,但你可以通過使用@public來實現。 從邏輯上講,您也可以將它們定義為@private@protected

通常我@synthesize @property因為我想要從類的外部訪問ivar,也因為我想要一個getter和setter方法。

一般意見是您應盡可能使用屬性。 如果您仍有疑問,請參閱Apple的建議:

通常,即使您從其自己的實現中訪問對象的屬性,也應該使用訪問器方法或點語法進行屬性訪問,在這種情況下,您應該使用self

...

編寫初始化,釋放或自定義訪問器方法時,此規則的例外情況

...

您應該始終直接從初始化方法中訪問實例變量,因為在設置屬性時,對象的其余部分可能尚未完全初始化

請閱讀此處的整個文檔以便更好地理解該主題。

至於性能問題,對於大多數應用程序而言,收益微不足道。 閱讀本文以獲得非常詳細的描述。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM