5.4 SEL类型
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为示意图仅供参考,我们可以暂时认为是这样的)。
[img]http://img.ddvip.com/2009_04_20/1240215192_ddvip_2013.png[/img]
图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也就是一个整数来查找方法,由于整数的查找和匹配比字符串要快得多,所以这样可以在某种程度上提高执行的效率。
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为示意图仅供参考,我们可以暂时认为是这样的)。
[img]http://img.ddvip.com/2009_04_20/1240215192_ddvip_2013.png[/img]
图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也就是一个整数来查找方法,由于整数的查找和匹配比字符串要快得多,所以这样可以在某种程度上提高执行的效率。