OC屬性與實例變量

OC屬性與實例變量

不管是java仍是c++這些面向對象的語言都會有屬性這一律念,一般而言,對於java屬性和實例變量沒有什麼區別,java官方定義的屬性以下:java

屬性是指get或者set方法名 去掉get或者set後,把剩餘的部分首字母改成小寫後,即爲這個類的屬性ios

其實objective-C與之相似,可是在通常的開發中,oc類的實例變量都不會被直接讀寫,而是經過getter和setter方法來進行讀寫操做。緣由以下:c++

  • 直接讀寫實例變量實質上是在編譯的過程當中,對.h文件中聲明的各個實例變量的偏移量進行操做。衆所周知,OC屬於運行時的動態語言。若是在運行時再添加實例變量,則原來的實際偏移量就會出現錯誤,內存佈局的改變會致使直接讀寫實例變量出現錯誤。佈局

    可是若是將實例變量的讀寫修改成經過getter和setter方式的通知(OC的方法可看做爲消息傳遞),而這些對象方法則存於類對象中,這樣就能夠解決上述問題。code

    OC將實例變量看成一種存儲偏移量所用的「特殊變量」,並將其交給類對象來進行保管,這樣作的好處就是系統會在運行期進行查找,若類的定義在運行期改變了,那麼存儲的偏移量也就隨之改變。對象

  • 經過setter方法來修改類的實例變量,還能夠觸發屬性的KVO。若是是直接改變實例變量,則沒法觸發。內存

屬性的自動合成

使用 @property+類型名+屬性名 可讓編譯器自動編寫這些屬性須要的方法。開發

例如:get

@property NSString *autoCreatedStr

在添加了property關鍵字後,編譯器會自動合成如下的setter和getter方法:編譯器

- (void) setAutoCreatedStr:(NSString *)autoCreatedStr;
- (NSString *) autoCreatedStr;

在自動合成屬性前,編譯器會自動爲屬性提供對應的實例變量,實例變量一般如下劃線開頭+屬性名:

NSString *_autoCreatedStr;

@synthesize關鍵字

在iOS6以前,編譯器是不會在設置完@Property後自動生成實例變量的,當設置完屬性後還要額外再加上一句:

@synthesize autoCreatedStr = _autocreatedStr;

加上這句之後,才能完成添加名爲「_autoCreatedStr」的實例變量。

可是在iOS6之後,LLVM編譯器就會爲每一個屬性添加上對應的@synthesize關鍵字,而且默認實例名爲:下劃線開頭+屬性名的格式。

因此在通常的開發中,只有想要自定義實例變量名的時候,纔會在.m文件中手動添加@synthesize來覆蓋原來的自動合成的如下劃線開頭的變量名。(通常來講都無需修改默認的實例變量名)

@dynamic關鍵字

dynamic關鍵字主要是用來通知編譯器無需由於@property關鍵字而自動合成屬性(包括生成實例變量和合成getter、setter方法)。

在編譯的過程當中,編譯器不會由於沒有定義讀寫方法而報錯,由於@dynamic關鍵字默認了讀寫方法會在運行時生成。例如在分類中利用關聯對象來給分類添加屬性等。

總結

  • OC開發中,一般不會直接對實例變量操做,而是經過getter和setter方法來對實例變量來進行讀寫。
  • ios6後property關鍵字會自動合成實例變量和讀寫方法。
  • dynamic關鍵字大部分狀況其實用不到。
相關文章
相關標籤/搜索