关于SEL的一些总结
1.SEL的概述
SEL就是對方法的一種包裝,是表示一個方法的selector的指針。包裝的SEL類型數(shù)據(jù)它對應相應的方法地址,找到方法地址就可以調(diào)用方法,其定義如下:
objc_selector結構體的詳細定義沒有在頭文件中找到。方法的selector用于表示運行時方法的名字。Objective-C在編譯時,會依據(jù)每一個方法的名字、參數(shù)序列,生成一個唯一的整型標識(Int類型的地址),這個標識就是SEL。不用的類里面的相同名字相同聲明的方法的身份證明是一樣的。這樣在程序執(zhí)行的時候,runtime就不用費力的進行方法的名字比較來確定是執(zhí)行哪一個方法了,只是通過一個整數(shù)的尋找就可以馬上定位到相應的方法,然后找到相應的方法的入口地址,這樣方法就可以被執(zhí)行了。
示例代碼:
ViewController.m
#import "ViewController.h" #import "Selector.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view, typically from a nib.Selector * select =[[Selector alloc]init];[select performSelector:@selector(viewDidLoad) withObject:nil];SEL sel1 =@selector(viewDidLoad);NSLog(@"sel1:%p",sel1);NSLog(@"viewDidLoad:%p",_cmd);//_cmd本身代表所在方法的SEL } @end Selector.m #import "Selector.h" @implementation Selector - (void)viewDidLoad {NSLog(@"Selector:%p",_cmd); } @end上面的輸出為:
2016-04-27 11:37:53.883 SEL? @selector()[6278:61711] Selector:0x106f674d5
2016-04-27 11:37:53.884 SEL? @selector()[6278:61711] sel1:0x106f674d5
2016-04-27 11:37:53.884 SEL? @selector()[6278:61711] viewDidLoad:0x106f674d5
注意點:
兩個類之間,不管它們是父類與子類的關系,還是之間沒有這種關系,只要方法名相同,那么方法的SEL就是一樣的。每一個方法都對應著一個SEL。所以在 Objective-C同一個類(及類的繼承體系)中,不能存在2個同名的方法,即使參數(shù)類型不同也不行。相同的方法只能對應一個SEL。這也就導致 Objective-C在處理相同方法名且參數(shù)個數(shù)相同但類型不同的方法方面的能力很差。如在某個類中定義以下兩個方法:
- (void)setWidth:(int)width;- (void)setWidth:(double)width;
當然,不同的類可以擁有相同的selector,這個沒有問題。不同類的實例對象執(zhí)行相同的selector時,會在各自的方法列表中去根據(jù)selector去尋找自己對應的IMP。
2.SEL的理解
工程中的所有的SEL組成一個Set集合,Set的特點就是唯一,因此SEL是唯一的。因此,如果我們想到這個方法集合中查找某個方法時,只需要去找到這個方法對應的SEL就行了,SEL實際上就是根據(jù)方法名hash化了的一個字符串,而對于字符串的比較僅僅需要比較他們的地址就可以了,可以說速度 上無語倫比!!但是,有一個問題,就是數(shù)量增多會增大hash沖突而導致的性能下降(或是沒有沖突,因為也可能用的是perfect hash)。但是不管使用什么樣的方法加速,如果能夠將總量減少(多個方法可能對應同一個SEL),那將是最犀利的方法。那么,我們就不難理解,為什么 SEL僅僅是函數(shù)名了。
本質(zhì)上,SEL只是一個指向方法的指針(準確的說,只是一個根據(jù)方法名hash化了的KEY值,能唯一代表一個方法),它的存在只是為了加快方法的查詢速度。這個查找過程我們將在下面討論。
我們可以在運行時添加新的selector,也可以在運行時獲取已存在的selector,
我們可以通過下面三種方法來獲取SEL:
1. sel_registerName函數(shù)2. Objective-C編譯器提供的@selector()
3. NSSelectorFromString()方法
SEL的用法主要有一下幾種
1.SEL 變量名 = @selector(方法名字); //注意有參數(shù)時要帶上:
2.SEL 變量名 = NSSelectorFromString(方法名字的字符串);
3.NSString *變量名 = NSStringFromSelector(SEL參數(shù));
參考:
? 1.http://www.cnblogs.com/yaski/archive/2009/04/05/1429735.html
總結
以上是生活随笔為你收集整理的关于SEL的一些总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何更改文件夹图标和颜色
- 下一篇: RFC 文档中文目录