自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

解析Objective-C反射

移動開發(fā) iOS
Objective-C有一個(gè)定位危機(jī):它是解釋型語言還是編譯語言?運(yùn)行時(shí)很大程度上是動態(tài)的。和C++不同,Objective-C是運(yùn)行時(shí)綁定的。這也是為什么我們可以在實(shí)現(xiàn)時(shí)定義一個(gè)從來沒有在頭文件中聲明的方法,

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

在運(yùn)行時(shí)可以窺視到一個(gè)對象的類元數(shù)據(jù)真的很不可思議,盡管這些可能不會在日常應(yīng)用編程中經(jīng)常使用到。從Java轉(zhuǎn)到Objective-C的程序員應(yīng)該會樂見Objective-C也支持反射。實(shí)際上,Objective-C有很多諸如動態(tài)改變類定義以及創(chuàng)建一個(gè)新類的動態(tài)特征。

不過很難說這些功能有多大的作用,這也讓我覺得Objective-C是一個(gè)有些臃腫的語言。在我看來,Objective-C有一個(gè)定位危機(jī):它是解釋型語言還是編譯語言?運(yùn)行時(shí)很大程度上是動態(tài)的。和C++不同,Objective-C是運(yùn)行時(shí)綁定的。這也是為什么我們可以在實(shí)現(xiàn)時(shí)定義一個(gè)從來沒有在頭文件中聲明的方法,或者通過Category擴(kuò)展類。不幸的是由于這種臃腫使得找到一些日常編程中有用的東西變得困難,本文就是要去發(fā)現(xiàn)其中的一些“寶藏”。

根類NSObject

大部分(如果不是全部的話)的動態(tài)反射支持來自NSObject 類。和Java的Object對象類似,NSObject是所有類(除了一些很少見的例外)的根類。所以所有你寫的類應(yīng)該都可以支持反射。需要指出的所有這些的反射支持并不是Objective-C語言的一部分,而是源于NS*的運(yùn)行時(shí)環(huán)境。這也是為什么這些東西感覺被加入一些額外東東的原因。因?yàn)樗褪潜患尤肓祟~外東東。

獲取類的元數(shù)據(jù) 通過調(diào)用如下的類方法你就可以獲取到一個(gè)對象的類的元數(shù)據(jù):

  1. Class c = [self class]; 

該方法既是實(shí)例方法也是類方法。它返回一個(gè)帶有很多神奇信息的C構(gòu)造體,比如實(shí)例變量、方法等等。所有這些和java.lang.reflect包相比都有些過時(shí)了,利用Objective-C訪問這些信息的接口看起來很復(fù)雜。這可能就是故意設(shè)計(jì)成這樣來“過濾”一些不合格的程序員。目前為止我唯一使用這些的地方就是為下面將要介紹的isKindOfClass:方法提供參數(shù)。一直以來我都不需要去窺視類結(jié)構(gòu)的內(nèi)容。

動態(tài)方程調(diào)用我已經(jīng)在方法調(diào)用一文中介紹了反射的一個(gè)方面。這使得你可以在運(yùn)行時(shí)創(chuàng)建一個(gè)方法調(diào)用并傳入?yún)?shù)。這和Java中使用java.lang.reflect.Method類很相似。

檢查繼承關(guān)系

Java有一個(gè)名為instanceof的操作符可以用來檢查一個(gè)對象是否是一個(gè)特定類或者接口的實(shí)例。 Objective-C也有類似的功能,就是通過isKindOfClass:方法。isKindOfClass:會在消息接收者是指定類及其子類的實(shí)例的情況下返回YES。比如有一個(gè)關(guān)聯(lián)的指針數(shù)組,這樣就可以根據(jù)其類型進(jìn)行不同的操作:

  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 } 

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

檢查是否符合協(xié)議 和實(shí)例檢查類似,你可以測試一個(gè)對象是否符合特定的協(xié)議。Java在類和接口的情況下都使用instanceof 方法搞定,但Objective-C使用了一個(gè)更笨重的方法。在測試是否合規(guī)的時(shí)候,應(yīng)該使用conformsToProtocol:方法:

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

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

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

當(dāng)然,利用Objective-C反射你可以做更多的事情,這里我只是嘗試談?wù)?strong>反射機(jī)制最常見的應(yīng)用。如果你需要在你的軟件中加入核心的動態(tài)特性,你就需要熟悉下這些文檔:

  1. Runtime Programming Guide: Introduction Runtime Reference 

小結(jié):解析Objective-C反射的內(nèi)容介紹完了,希望通過本文的學(xué)習(xí)能對你有所幫助!

責(zé)任編輯:zhaolei 來源: 互聯(lián)網(wǎng)
相關(guān)推薦

2013-03-27 12:54:00

iOS開發(fā)Objective-C

2011-08-05 15:46:32

Objective-C 程序設(shè)計(jì)

2011-08-11 17:39:25

Objective-C筆試題

2011-08-15 14:02:36

Objective-C

2011-07-29 16:08:31

Objective-C 內(nèi)存

2013-06-20 10:40:32

Objective-C實(shí)現(xiàn)截圖

2011-05-11 11:20:26

Objective-C

2011-05-11 15:58:34

Objective-C

2011-08-04 15:52:48

Objective-C HTML

2011-08-04 14:58:37

Objective-C Cocoa NSString

2011-08-02 13:16:36

Objective-C 語法 函數(shù)

2011-05-11 13:54:08

Objective-C

2011-05-11 15:45:50

內(nèi)存管理Objective-C

2013-08-21 14:57:42

objective-c問題

2011-05-11 14:06:49

Objective-C

2011-08-04 11:15:46

Objective-C 構(gòu)造函數(shù) 構(gòu)造方法

2014-04-30 10:16:04

Objective-CiOS語法

2011-08-03 16:55:05

Objective-C 代理

2011-07-08 13:49:46

Objective-C UUID

2011-07-29 16:16:30

Objective-c block
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號