关闭

object c中的selector sef

480人阅读 评论(0) 收藏 举报

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也就是一个整数来查找方法,由于整数的查找和匹配比字符串要快得多,所以这样可以在某种程度上提高执行的效率。



--------------------------------------

Objective-C中调用函数的方法是“消息传递”,这个和普通的函数调用的区别是,你可以随时对一个对象传递任何消息,而不需要在编译的时候声明这些方法。所以Objective-C可以在runtime的时候传递人和消息。

 

首先介绍两个方法 SEL和@selector

根据AppleObjective-C Runtime Reference官方文档这个传递消息的函数就是 id objc_msgSend(id theReceiver, SEL theSelector, …)

theReceiver是接受消息的对象类型是id,theSelector是消息名称类型是SEL。下边代码我们来看看如何来生成一个SEL,如果传递消息。

首先建立一个简单的函数

- (void) fooNoInputs {

NSLog(@"Does nothing");

}

然后调用它

[self performSelector:@selector(fooNoInputs)];

第二个试验看看如何在消息中传递参数

我们建立一个有input参数的函数

- (void) fooOneIput:(NSString*) first {

NSLog(@"Logs %@", first);

}

然后调用它

[self performSelector:@selector(fooOneInput:) withObject:@"first"];

第三个试验更多的参数

- (void) fooFirstInput:(NSString*) first secondInput:(NSString*) second {

NSLog(@"Logs %@ then %@", first, second);

}

然后调用它

[self performSelector:@selector(fooFirstInput:secondInput:) withObject:@"first" withObject:@"second"];

第四个试验如何建立动态的函数,然后调用他们?我们需要建立一个selector

SEL myTestSelector = @selector(myTest:);

并且我们调用的函数在另外一个Class内

- (void)abcWithAAA: (NSNumber *)number {

int primaryKey = [number intValue];

NSLog("%i", primaryKey);

}

MethodForSelectors * mfs = [MethodForSelectors alloc];

NSArray *Arrays = [NSArray arrayWithObjects:@"AAA", @"BBB", nil];

for ( NSString *array in Arrays ){

SEL customSelector = NSSelectorFromString([NSStringstringWithFormat:@"abcWith%@:", array]);

mfs = [[MethodForSelectors alloc] performSelector:customSelector withObject:0];

}

完整的代码:

@implementation ClassForSelectors
- (void) fooNoInputs {

NSLog(@"Does nothing");

}

- (void) fooOneIput:(NSString*) first {

NSLog(@"Logs %@", first);

}

- (void) fooFirstInput:(NSString*) first secondInput:(NSString*) second {

NSLog(@"Logs %@ then %@", first, second);

}

 

- (NSArray *)abcWithAAA: (NSNumber *)number {

int primaryKey = [number intValue];

NSLog("%i", primaryKey);

}

 

- (void) performMethodsViaSelectors {

[self performSelector:@selector(fooNoInputs)];

[self performSelector:@selector(fooOneInput:) withObject:@"first"];

[self performSelector:@selector(fooFirstInput:secondInput:) withObject:@"first" withObject:@"second"];

}

 

- (void) performDynamicMethodsViaSelectors {

MethodForSelectors * mfs = [MethodForSelectors alloc];

NSArray *Arrays = [NSArray arrayWithObjects:@"AAA"@"BBB"nil];

forNSString *array in Arrays ){

SEL customSelector = NSSelectorFromString([NSStringstringWithFormat:@"abcWith%@:", array]);

mfs = [[MethodForSelectors allocperformSelector:customSelector withObject:0];

}

}

@end

 
@implementation MethodForSelectors

- (void)abcWithAAA: (NSNumber *)number {

NSLog("%i", number);

}

@end

--EOF--作者:Buro#79xxd出处:http://www.cnblogs.com/buro79xxd/文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:99510次
    • 积分:2005
    • 等级:
    • 排名:第19297名
    • 原创:87篇
    • 转载:121篇
    • 译文:0篇
    • 评论:6条
    最新评论