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


先看tomcat里用到的代碼:

    //然后開始動畫
    //把圖片放到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 語法快速過(5)中的SEL數據類型

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

typedef struct objc_selector *SEL;

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

具體這objc_selector結構體是什么,取決與使用GNU的還是Apple的運行時, 在Mac OS X中SEL其實被映射為一個C字符串,可以看作是方法的名字,它並不指向具體方法實現(IMP類型才是)。

對於所有的類,只要方法名是相同的,產生的selector都是一樣的。

 

看官方文檔;

- (id)performSelector:(SEL)aSelector

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

 

看到這里,發現@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庫之間對象,控制之間通訊都是在這個基礎構建的。 

 

歡迎關注

 

dashuai的博客是終身學習踐行者,大廠程序員,且專注於工作經驗、學習筆記的分享和日常吐槽,包括但不限於互聯網行業,附帶分享一些PDF電子書,資料,幫忙內推,歡迎拍磚!

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM