[Objective-C]SEL類型、@selector選擇器

object c中的selector



其作用相當於函數指針,現在我看到的大多說用法都是在調用某些函數需要傳遞一個 函數指針 參數時,使用@selector。它會在當前類裏面查找selector後面所跟的函數,返回一個SEL類型的值。
SEL變量的執行.用performSelecor方法來執行.
[對象 performSelector:SEL變量 withObject:參數1 withObject:參數2];
在調用respondsToSelector:@selector(method)時,這個method只有在該方法存在參數時需要 ":",如果該方法不需要參數就不需要加這個冒號。否則,編譯不會報錯,只是執行返回的值不對。當然如果方法有多個參數,需要多個冒號,參數有名稱的需要帶上參數名稱。
如:有如下方法:
-(NSString*)toXmlString;
此時調用類似於:
[self respondsToSelector:@selector(toXmlString)]
如果toXmlString方法的定義爲:
-(NSString*)toXmlString:(NSString*)prefix;
那麼調用就必須加上冒號,如:[self respondsToSelector:@selector(toXmlString:)]
·-(BOOL) isKindOfClass: classObj 用來判斷是否是某個類或其子類的實例
·-(BOOL) isMemberOfClass: classObj 用來判斷是否是某個類的實例
·-(BOOL) respondsToSelector: selector 用來判斷是否有以某個名字命名的方法(被封裝在一個selector的對象裏傳遞)
·+(BOOL) instancesRespondToSelector: selector 用來判斷實例是否有以某個名字命名的方法. 和上面一個不同之處在於, 前面這個方法可以用在實例和類上,而此方法只能用在類上.
·-(id) performSelector: selector 執行某個方法




[Objective-C]SEL類型、@selector選擇器


1     id cattle[3]; 
2     SEL say; 
3     SEL skin; 

  其中id cattle[3]定義了一個數組用於存儲Cattle或者Bull對象。這一行代碼估計大家都很熟悉,筆者就不贅述了。像這樣的傳統的數組並不能完全滿足我們的需求,當我們需要做諸如追加,刪除等操作的時候,會很不方便。在隨後的章節裏面筆者將要向大家介紹傳統數組的替代解決方案NSArray。 

  上一段代碼的第二行和第三行是本節所關注的,就是SEL類型。Objective-C在編譯的時候,會根據方法的名字(包括參數序列),生成一個用 來區分這個方法的唯一的一個ID,這個ID就是SEL類型的。我們需要注意的是,只要方法的名字(包括參數序列)相同,那麼它們的ID都是相同的。就是 說,不管是超類還是子類,不管是有沒有超類和子類的關係,只要名字相同那麼ID就是一樣的。除了函數名字和ID,編譯器當然還要把方法編譯成爲機器可以執 行的代碼,這樣,在一個編譯好的類裏面,就產生了如下圖所示方法的表格示意圖(本構造屬於筆者推測,沒有得到官方證實,所以圖5-2爲示意圖僅供參考,我們可以暫時認爲是這樣的)。 

Objective-C學習---------SEL類型  
圖5-2,方法的表格示意圖 

  請注意setSkinColor後面有一個冒號,因爲它是帶參數的。由於存在這樣的一個表格,所以在程序執行的時候,我們可以方便的通過方法的名字,獲取到方法的ID也就是我們所說的SEL,反之亦然。具體的使用方法如下: 


1     SEL 變量名 = @selector(方法名字); 
2     SEL 變量名 = NSSelectorFromString(方法名字的字符串); 
3     NSString *變量名 = NSStringFromSelector(SEL參數); 


其中第1行是直接在程序裏面寫上方法的名字,第2行是寫上方法名字的字符串,第3行是通過SEL變量獲得方法的名字。我們得到了SEL變量之後,可以通過下面的調用來給一個對象發送消息: 

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

  這樣的機制大大的增加了我們的程序的靈活性,我們可以通過給一個方法傳遞SEL參數,讓這個方法動態的執行某一個方法;我們也可以通過配置文件指定需要執行的方法,程序讀取配置文件之後把方法的字符串翻譯成爲SEL變量然後給相應的對象發送這個消息。 

  從效率的角度上來說,執行的時候不是通過方法名字而是方法ID也就是一個整數來查找方法,由於整數的查找和匹配比字符串要快得多,所以這樣可以在某種程度上提高執行的效率。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章