程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Objective-C中的屬性(property)

Objective-C中的屬性(property)

編輯:關於C語言

Objective-C中的屬性(property)   它組合了新的預編譯指令和新的屬性訪問的語法,新的屬性功能顯著減少了必須編寫的冗長代碼的數量。 下面我們來比較下面的代碼   復制代碼 //第一種聲明方法 -(void)setRainHandling:(float) rainHanding;   -(float) rainHandling;    -(void)setSnowHandling:(float) snowHandling;   -(float) snowHandling;   //第二種聲明方法 @property float rainHandling;   @property float snowHandling; 復制代碼     以上兩段代碼的作用是完全一樣的,由此我們可以得出屬性的作用是:   @property預編譯指令的作用是自動聲明屬性的setter和getter方法,事實上,屬性的名稱不必與實例變量的名稱相同,但大多數情況下它們是一樣的。 我們知道了函數的settter和getter方法的聲明,但是如何實現呢?我們接著看   復制代碼 //第一種實現方法 -(void)setRainHandling:(float) rh {     rainHandling =rh; }   -(float) rainHandling {     return rainHandling; }   -(void)setSnowHandling:(float) sh {     snowHandling =sh; }   -(float) snowHandling {     return snowHandling; } //第二種實現方法 @synthesize rainHandling;   @synthesize snowHandling; 復制代碼     我們的目的是徹底的刪除setter和getter方法,用以上的兩行代碼就可以完全代替。   對於synthesize這種編譯器的功能有以下幾點需要說明:   @sythesize它表示“創建了該屬性的訪問代碼”。當遇到@sythesize rainHandling;這行代碼時,編譯器將添加實現 -setRainHandling:和-rainHandling方法的預編譯代碼。 Cocoa的訪問器編寫實用工具和其他平台上的UI生成器可以生成源代碼,這些源代碼隨後會被編譯。但是@sythesize預編譯指令不同於代碼生成。你永遠也不會看到實現-setRainHandling:和-ranHandling的代碼,這些方法確實存在並可以調用。 在X-code 4.5以後的版本中,可以不必使用@sythesize了。 所有的屬性都是基於變量的,所以在你合成setter和getter方法的時候,編譯器會自動創建與屬性名稱相同的實例變量。如果你沒有聲明這些變量,編譯器也會聲明的。如果我們不去自己實現@sythesize,編譯器會給我們生成一個下滑線(_)開頭的實例變量。如在頭文件的定義中寫@property (copy) NSString name; 在其實現中會有一個_name的實例變量。 點表達式的妙用   Objective-C 2.0的屬性引用了一些新的語法特性,使我們更加容易訪問對象的屬性,也就是點表達式。 如果點表達式出現了等號(=)的左邊,該變量名稱的setter方法將被調用。如果點表達式出現在了對象變量的右邊,則該變量的getter方法將被調用。 點表達式只是調用訪問方法的一種便捷方式,並沒有什麼神秘之處。 屬性的擴展   assign //簡單賦值,主要用於基本數據類型 copy //創建一個新的對象,新的對象和舊對象是獨立的兩個對象 retain //將對象計數器加1 readonly //表示只讀屬性  只會生成getter方法 不會生成setter方法 readwrite //默認值,表求生成setter和getter方法 nonatomic //非原子訪問,不加同步 ,多線程並發訪問提高性能 (對多線程的保護,防止在未寫完,被另一個線程讀取,造成數據錯誤) 名稱的使用     一種非常普遍的情況是屬性的名稱與支持屬性的實例變量名稱相同,不過,有時候你可能希望實例變量是一個名稱,而公開的屬性是另一個名稱。   復制代碼 //頭文件的定義 #import "Tire.h" //關於適應所有天氣的Tire類的聲明與定義   @interface AllWeatherTire : Tire {     NSString *tireName; }   @property float rainHanding; @property float snowHanding; //用於給我們我的輪胎起一個名字 @property (copy)NSString *name;   //實現 #import "AllWeatherTire.h" @implementation AllWeatherTire @synthesize name = tireName;   - (NSString*)description {     NSString *desc;       desc = [NSString stringWithFormat:@"AllWeatherTier:name is %@,%.1f,%.1f, %.1f, %.1f",               self.name,self.pressure,self.treadDepth,self.rainHanding,self.snowHanding];       return desc; } 復制代碼         在這裡編譯器仍創建-setName:和-name方法,但在其實現代碼中用的卻是tireName實例變量。不過這樣做的話,編譯的時候將會遇到一些錯誤。因為我們直接訪問的實例變量已經被修改了。我們可以選擇用搜索並替換的name的方式來解決,也可以將實例變量的直接調用改成用訪問的方法。比如在init方法中把 name =@“Car” 改成self.name =@"Car".   自己動手有時更好   我們之前提到過屬性是基於變量的,並且編譯器會為你創建setter和getter方法。但是如果你不想要變量、setter和getter方法的話應該怎麼辦? 答案是使用@dynamic關鍵字。 如果你聲明了dynamic屬性,並且企圖調用不存在的getter和setter方法,你將會得到一個錯誤。 復制代碼 @property(readonly) float bodyMassIndex;   @dynamic bodyMassIndex;   -(float)bodyMassIndex   {   ///  ; } //如果調用不存在的setter和getter方法會報錯。 復制代碼 屬性的缺點     屬性不是萬能的,如果方法並不適合屬性所胡涵蓋的較小范圍的話。屬性只支持替代 -setBlah和-blah方法,但是不支持那些需要接收額外參數的方法。例如:car對象中tire對象的代碼。   -(void)setTire:(Tire *)tire atIndex:(int)index;   -(Tire *)tireAtIndex:(int)index; 屬性的總結     本文主要介紹了屬性。在為對象變量執行常見的操作時,利用屬性可以減少需要編寫以及隨後需要閱讀的代碼數量。使用@propert預編譯指令可以告訴編譯器:“嘿,這個對象具有這些類型的特性” 你還可以讓屬性傳遞其他信息,比如可變性(只讀或者讀寫)。編譯器在後台會自動生成對象變量的setter和getter方法。     使用@sythesize預編譯指令可以通知編譯器生成訪問的方法。你還可以控制由編譯器生成的訪問方法對哪些實例變量起作用。如果不想使用默認的行為,你完全可以編寫自己的訪問方法。你還可以使用@dynamic指令告訴編譯器不要生成變量和代碼。     盡管點表達式通常出現在有屬性的代碼中,但是它只是調用對象的setter和getter方法的一種便捷方式。點表達式法減少了需要鍵入的字符數量,而且進一步方便了曾經使用其他語言的編程人員。  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved