objective-c中的@selector()和 c /c++的函數指針

先看tomcat裏用到的代碼:html

    //而後開始動畫
    //把圖片放到animationImages,接受數組參數
    self.tom.animationImages = arrayImage;
    //設置時間間隔,81張圖,圖多就播的時間稍微長,不然短
    self.tom.animationDuration = arrayImage.count * 0.074;
    //設置重複次數
    self.tom.animationRepeatCount = 1;
    //開始動畫
    [self.tom startAnimating];
    //結束動畫,應該等等再清空
    [self.tom performSelector:@selector(setAnimationImages:) withObject:nil afterDelay:self.tom.animationDuration];

最後一句代碼,延遲加載 set 方法的過程。@selector(xxxx)的做用是找到名字爲xxxx的方法。就是說去調用a對象的b方法,和[a b];的意思同樣,可是這樣更加動態一些。返回的類型是SEL,看方法說明的時候若是參數類型是SEL,那麼就是要接受@selector(xxxx)返回的值objective-c

回憶:數組

objective-c 語法快速過(5)中的SEL數據類型tomcat

每一個類的方法列表都存儲在類對象中,每一個方法都有一個與之對應的SEL類型的數據,根據一個SEL類型的數據就能夠找到方法的地址,進而調用方法。SEL類型的定義:函數

typedef struct objc_selector *SEL;

SEL實際上是對方法的一種包裝,將方法包裝成一個SEL類型的數據,去找對應的方法地址。找到方法地址就能夠調用方法,其實發送的消息就是SEL。post

具體這objc_selector結構體是什麼,取決與使用GNU的仍是Apple的運行時, 在Mac OS X中SEL其實被映射爲一個C字符串,能夠看做是方法的名字,它並不指向具體方法實現(IMP類型纔是)。動畫

對於全部的類,只要方法名是相同的,產生的selector都是同樣的。spa

 

看官方文檔;指針

- (id)performSelector:(SEL)aSelector

把指定的消息發送給接收方,餅返回執行的結果,也就是說 perform(自己就有履行執行的意思)Selector :xxx,是執行名字爲 xxx 方法的方法,只不過是間接去執行,經過 sel 參數(使用@selector(方法的名字)的返回sel 類型),找到方法。code

 

看到這裏,發現@selector(methodName)很是相似 c 語言的函數指針的概念。

C語言中,能夠把函數名直接賦給一個函數指針,而OC的類不能直接應用函數指針,這樣只能作一個@selector語法來取.它的return結果是一個SEL類型。這個類型本質是類方法的編號(函數地址)。

 

回憶函數指針

 

函數也具備地址,指向函數的指針指向(保存)了函數代碼起始處的地址,聲明一個函數指針,必須先聲明它指向的函數類型(返回類型和參量類型),聲明指向函數的指針,函數指針能夠做爲另外一個函數的參數,告訴第二個函數使用哪一個函數。

 

    void ToUpper(char *);//先聲明函數


    ……


    void (*p)(char *);//指針p是指向函數ToUpper的指針

即:(*p)也是一個函數,char*是它的參量,void是返回類型,表達式(*p)代替了函數名。由於*運算符優先級低於(),故必須加括號——(*p),省略掉圓括號意義就變了:

 

void  * p(char *);//意思是p是一個函數,返回一個空指針類型

聲明瞭函數指針,則能夠用函數名錶示函數的地址,固然指針也能夠。函數指針最廣泛的用法,是做爲函數參數. 且只能指向函數都是相同類型的,能夠用函數指針做爲函數的參數,也能用函數名做爲參數(函數名看做是函數地址),不能有函數數組!可是能夠有函數指針的數組

 

再看 oc,取得selector值.

 

//object-c的選擇器
@interface method
-(int)add:(int) val;
@end

SEL fun ; //至關於定義一個方法指針
fun = @selector(add:);

 

注意;

能夠用字符串來找方法

SEL 變量名 = NSSelectorFromString(方法名字的字符串);

能夠運行中用SEL變量反向查出方法名字字符串
NSString *變量名 = NSStringFromSelector(SEL參數);

取得相應值後,怎麼處理SEL值,這一點仍然與函數指針同樣,就是執行它。SEL變量的執行,用performSelecor對象方法來執行.

[對象 performSelector:SEL變量 withObject:參數1 withObject:參數2];

 

selector的應用場合

是能讓Objective-C動態調用方法的玩意.

是 object-c 的動態後綁定技術

能夠經過字符串訪問函數

selector本質是跟C的回調函數同樣。主要用於兩個對象之間進行鬆耦合的通信.這種方法基本上整個Cocoa庫之間對象,控制之間通信都是在這個基礎構建的。 

相關文章
相關標籤/搜索