我们有时在写iOS程序或者看一些框架代码时会看到SEL和IMP的方法,那这两个到底是什么呢?
SEL:类成员方法的指针,但是不同于C语言的函数指针,函数指针直接保存了方法的地址,但SEL只是方法编号;
IMP:一个函数指针,保存了方法地址;
SEL和IMP的关系
每一个继承于NSobject的类都能自动获的runtime的支持,在这样的类中,有一个isa指针,指向该类定义的数据结构体,这个结构体是编译器编译时为类创建的.在这个结构体中包括了指向其父类类定义的指针及Dispatch table,Dispatch table 是一张SEL和IMP的对应表(可以参考:(http://blog.csdn.net/fengsh998/article/details/8614486)) ; 也就是说方法编号SEL最后还要通过Dispatch table表找到对应的IMP,IMP是一个函数指针,然后去执行这个方法;
为什么不直接获得函数指针,而要从SEL这个编号走一圈再回到函数指针呢?
有了SEl的这个中间过程,可以对一个编号和什么方法映射做些操作,也就是说一个SEL可以指向不同的函数指针,这样就完成可以一个方法名在不同时候对应不同的函数体;另外可以将SEL作为参数传递给不同的类执行.也就是说某些业务我们 只知道方法名但是要根据不同情况让不同的类执行的时候,SEL可以帮助我们.写了一个简单的demo如下:
先写了一个字典数组,
self.arryList = @[@{@"title":@"第一个view",@"sel": NSStringFromSelector(@selector(fristview))},
@{@"title":@"第二个view",@"sel":NSStringFromSelector(@selector(secondview))},
@{@"title":@"第三个view",@"sel":NSStringFromSelector(@selector(thirdview))},
@{@"title":@"第三个view",@"sel":NSStringFromSelector(@selector(thirdview))},
@{@"title":@"第四个view",@"sel":NSStringFromSelector(@selector(fourview))},
@{@"title":@"第五个view",@"sel":NSStringFromSelector(@selector(fiveview))},
@{@"title":@"第六个view",@"sel":NSStringFromSelector(@selector(sixview))}
];
然后给页面加载一个tableview,对应代理方法中,
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
//取类方法的编号
SEL selector = NSSelectorFromString(self.arryList[indexPath.row][@"sel"]);
//IMP获得
IMP imp = [self methodForSelector:selector];
void (*func)(id,SEL) = (void *)imp;
//IMP使用
func(self,selector);
}
这样就能实现一个简单的加载cell和点击cell跳转页面了
本文只是简单介绍SEL和IMP的理解和简单应用,如有不对之处欢迎指正...