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為僅供參考,我們可以暫時認為是這樣的)。
圖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也就是一個整數來尋找方法,由於整數的尋找和匹配比字串要快得多,所以這樣可以在某種程度上提高執行的效率。