iOS中成員變數和屬性區別,ios成員變數區別

來源:互聯網
上載者:User

iOS中成員變數和屬性區別,ios成員變數區別

原文連結:http://blog.csdn.net/u012946824/article/details/51788565

曆史由來:

接觸iOS的人都知道,@property聲明的屬性預設會產生一個_類型的成員變數,同時也會產生setter/getter方法。 
但這隻是在iOS5之後,蘋果推出的一個新機制。看老代碼時,經常看到一個大括弧裡面定義了成員變數,同時用了@property聲明,而且還在@implementation中使用@synthesize方法。 
如下:

Demo

@interface ViewController (){   // 1.聲明成員變數    NSString *myString;   } //2.在用@property@property(nonatomic, copy) NSString *myString;  @end@implementation ViewController//3.最後在@implementation中用synthesize產生set方法@synthesize myString;   @end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

其實,發生這種狀況根本原因是蘋果將預設編譯器從GCC轉換為LLVM(low level virtual machine),才不再需要為屬性聲明執行個體變數了。

在沒有更改之前,屬性的正常寫法需要成員變數+ @property + @synthesize 成員變數三個步驟。 
如果我們唯寫成員變數+ @property:

@interface GBViewController :UIViewController{    NSString *myString;}@property (nonatomic, strong) NSString *myString;@end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
編譯時間會警示告:Autosynthesized property 'myString' will use synthesized instance variable '_myString', not existing instance variable 'myString'
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

但更換為LLVM之後,編譯器在編譯過程中發現沒有新的執行個體變數後,就會產生一個底線開頭的執行個體變數。因此現在我們不必在聲明一個執行個體變數。(注意:==是不必要,不是不可以==) 
當然我們也熟知,@property聲明的屬性不僅僅預設給我們產生一個_類型的成員變數,同時也會產生setter/getter方法。

.m檔案中,編譯器也會自動的產生一個執行個體變數_myString。那麼在.m檔案中可以直接的使用_myString執行個體變數,也可以通過屬性self.myString.都是一樣的。

注意這裡的self.myString其實是調用的myString屬性的setter/getter方法。這與C++中點的使用是有區別的,C++中的點可以直接存取成員變數(也就是執行個體變數)。

例如在oc中有如下代碼

@interface MyViewController :UIViewController{    NSString *name;}@end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

在這段代碼裡面只是聲明了一個成員變數,並沒有setter/getter方法。所以訪問成員變數時,可以直接存取name,也可以像C++一樣用self->name來訪問,但絕對不能用self.name來訪問。

 
  • 擴充:很多人覺得OC中的點文法比較奇怪,實際是OC設計人員有意為之。
  • 點運算式(.)看起來與C語言中的結構體訪問以及java語言匯總的對象訪問有點類似,如果點運算式出現在等號  左邊,調用該屬性名稱的setter方法。如果點運算式出現在右邊,調用該屬性名稱的getter方法。
  • OC中點運算式(.)其實就是調用對象的settergetter方法的一種捷徑,self.myString = @"張三";實際就是[self setmyString:@"張三"];

首先我們要明白,@synthesize 產生了setter/getter方法。 
雖然現在直接使用@property時,編譯器會自動為你產生以底線開頭的執行個體變數_myString,不需要自己手動再去寫執行個體變數。而且也不在.m檔案中通過@synthesize myString;產生setter/getter方法。但在看老代碼的時候,我們依舊可以看到有人使用成員變數+ @synthesize 成員變數的形式。

那麼問題來了: 
我們能否認為新編譯器LLVM下的@property == 老編譯器GCC的 成員變數+ @property + @synthesize 成員變數呢?

答案是否定的。 
因為成員變數+ @property + @synthesize 成員變數的形式,編譯器不會幫我們產生_成員變數,因此不會操作_成員變數了; 
同時@synthesize 還有一個作用,可以指定與屬性對應的執行個體變數, 
例如@synthesize myString = xxx; 
那麼self.myString其實是操作的執行個體變數xxx,而非_String了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.