解析Objective-C反射

來源:互聯網
上載者:User

    Objective-C反射是本文要介紹的內容,我第一次接觸Java的時候就覺得整個反射包都很新穎,它使得Java和解釋型的指令碼語言更接近了,與此同時也拉開了和主流的C和C++的距離。

在運行時可以窺視到一個對象的類別中繼資料真的很不可思議,儘管這些可能不會在日常應用編程中經常使用到。從Java轉到Objective-C的程式員應該會樂見Objective-C也支援反射。實際上,Objective-C有很多諸如動態改變類定義以及建立一個新類的動態特徵。

不過很難說這些功能有多大的作用,這也讓我覺得Objective-C是一個有些臃腫的語言。在我看來,Objective-C有一個定位危機:它是解釋型語言還是編譯語言?運行時很大程度上是動態。和C++不同,Objective-C是運行時綁定的。這也是為什麼我們可以在實現時定義一個從來沒有在標頭檔中聲明的方法,或者通過Category擴充類。不幸的是由於這種臃腫使得找到一些日常編程中有用的東西變得困難,本文就是要去發現其中的一些“寶藏”。

根類NSObject

大部分(如果不是全部的話)的動態反射支援來自NSObject 類。和Java的Object對象類似,NSObject是所有類(除了一些很少見的例外)的根類。所以所有你寫的類應該都可以支援反射。需要指出的所有這些的反射支援並不是Objective-C語言的一部分,而是源於NS*的運行時環境。這也是為什麼這些東西感覺被加入一些額外東東的原因。因為它就是被加入了額外東東。

擷取類的中繼資料 通過調用如下的類方法你就可以擷取到一個對象的類的中繼資料:

  1. Class c = [self class]; 

該方法既是執行個體方法也是類方法。它返回一個帶有很多神奇資訊的C構造體,比如執行個體變數、方法等等。所有這些和java.lang.reflect包相比都有些過時了,利用Objective-C訪問這些資訊的介面看起來很複雜。這可能就是故意設計成這樣來“過濾”一些不合格的程式員。目前為止我唯一使用這些的地方就是為下面將要介紹的isKindOfClass:方法提供參數。一直以來我都不需要去窺視類結構的內容。

動態方程調用我已經在方法調用一文中介紹了反射的一個方面。這使得你可以在運行時建立一個方法調用並傳入參數。這和Java中使用java.lang.reflect.Method類很相似。

檢查繼承關係

Java有一個名為instanceof的操作符可以用來檢查一個對象是否是一個特定類或者介面的執行個體。 Objective-C也有類似的功能,就是通過isKindOfClass:方法。isKindOfClass:會在訊息接收者是指定類及其子類的執行個體的情況下返回YES。比如有一個關聯的指標數組,這樣就可以根據其類型進行不同的操作:

  1. for(BaseClass* base in myArray) {  
  2. if([base isKindOfClass:[ClassOne class]]) {  
  3. // do stuff specific to ClassOne  
  4. } else if([base isKindOfClass:[ClassTwo class]]) {  
  5. // do stuff specific to ClassTwo  
  6. } else if([base isKindOfClass:[ClassThree class]]) {  
  7. // do stuff specific to ClassThree }  
  8. // etc } 

如果你需要一個精確的類匹配,而不是匹配任何繼承類,你就可以使用isMemberOfClass:方法。

檢查是否符合協議 和執行個體檢查類似,你可以測試一個對象是否符合特定的協議。Java在類和介面的情況下都使用instanceof 方法搞定,但Objective-C使用了一個更笨重的方法。在測試是否合規的時候,應該使用conformsToProtocol:方法:

  1. BOOL conforms = [obj conformsToProtocol:@protocol(MyInterface)]; 

檢查方法是否存在對於像我這樣Java和C++的老手來說,如果不知道一個對象是否實現了一個方法就很奇怪了。但是Objective-C的類很大程度上是動態,你就需要檢查你需要的方法是否存在。這就需要respondsToSelector:方法。如下代碼就是檢查接收者是否實現(或者繼承)了指定方法:

  1. if([obj respondsToSelector:@selector(aMethod:)])   
  2. { // it's there, so we can call it [obj aMethod:YES];  
  3.  } 

當然,利用Objective-C反射你可以做更多的事情,這裡我只是嘗試談談反射機制最常見的應用。如果你需要在你的軟體中加入核心的動態特性,你就需要熟悉下這些文檔:

  1. Runtime Programming Guide: Introduction Runtime Reference 

小結:解析Objective-C反射的內容介紹完了,希望通過本文的學習能對你有所協助!

 

轉自:http://mobile.51cto.com/iphone-282485.htm

by sschu

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.