`

【Objective-C】Selector基本概念和操作

 
阅读更多


简而言之,你可以理解 @selector()就是取类方法的编号,他的行为基本可以等同C语言的中函数指针,只不过C语言中,可以把函数名直接赋给一个函数指针,而Objective-C的类不能直接应用函数指针,这样只能做一个@selector语法来取.
   
它的结果是一个SEL类型。这个类型本质是类方法的编号(函数地址)?因此我们有如下代码。

一、取得selector值.

C函数指针

  1. int add(int val)  
  2. {  
  3.   return val+1;  
  4. }  
  5.  
  6.  
  7. int (* c_func)(int val); //定义一个函数指针变量  
  8. _func = add ;  //把函数addr地址直接赋给c_func 

Objective-C的选择器,

  1. @interface foo  
  2. -(int)add:int val;  
  3. @end  
  4.  
  5.  
  6. SEL class_func ; //定义一个类方法指针  
  7. class_func = @selector(add:int); 

注意1. @selector是查找当前类的方法,而[object @selector(方法名:方法参数..) ] ;是取object对应类的相庆方法.

注意2.查找类方法时,除了方法名,方法参数也查询条件之一.

注意3. 可以用字符串来找方法 SEL 变量名 = NSSelectorFromString(方法名字的字符串);

注意4. 可以运行中用SEL变量反向查出方法名字字符串

  1. NSString *变量名 = NSStringFromSelector(SEL参数); 

二、执行selector值.

取得相庆值后,怎么处理SEL值呢,这一点仍然与函数指针一样,就是执行它
   
函数指针执行,(以下有几种等效形式)

  1. *c_func(10);  
  2. c_func(10); 

SEL变量的执行.用performSelecor方法来执行. 

  1. [对象 performSelector:SEL变量 withObject:参数1 withObject:参数2]; 

三.selector的应用场合

selector本质是跟C的回调函数一样。主要用于两个对象之间进行松耦合的通讯.这种方法很多开发环境用到。比如GTK,Delphi.基本上整个Cocoa库之间对象,控制之间通讯都是在这个基础构建的。



在Objective C中,selector有两个含义。
1. 当在源代码中发消息给对象的时候,selector指的是方法名
2. 当源代码被编译后,指的是替代方法名的唯一标识符(identifier)

编译后的selector的类型是SEL, 所有具有相同方法名的方法有相同的selector
你可以用selector来调用一个object的方法----->这个为Cocoa中target-action的设计模式提供了基础

method and selector
从效率上说,编译后的代码中,ASCII的名字不会被用做方法的selector,编译器会把方法名写到一张表格里,用一个唯一的标识符(identifier)与它对应
并且在运行时用这个标识符来表示方法。标识符是唯一的,selector也是唯一的,没有两个相同的标识符或者selector。


SEL and @selector
为了区别于其他的数据类型,编译后的selector的类型为SEL。 指令@selector可以引用编译后的selector,这个要比使用方法名要有效率。

Methods and selectors
编译后的方法指示方法名,而不是方法的实现。这是多态和动态绑定的基础。这能让你发送相同的消息给不同的类的接收器,如果类方法名和对象方法名一样,
那么他们的selector标识符也是一样的,但是这不会冲突,首先selecotr标示符不是方法的实现,只代表方法名,其次类方法名和对象方法名属于不同的域。

Method Return and Parameter Types

 消息程序只能通过selector来访问方法的实现,所以对待所有具有相同selector的方法都是一样的。消息程序通过selector来获取返回类型和参数的类型
因此动态绑定需要所有具有相同名字的方法的实现有相同的return类型和相同的参数类型。

Varying the Message at Runtime

performSelector: 
performSelector:withObject:
performSelector:withObject:withObject: 
以上3个定义在NSObject protocol里的方法,把SEL标识符作为他们的初始参数。3个方法都直接映射到消息函数,举个例子,

[friend performSelector:@selector(gossipAbout:)withObject:aNeighbor];
相当于
[friend gossipAbout:aNeighbor];

有了这些方法,消息和接收对象在运行时是可变的。变量名可以用在消息表达式里,例:
id helper = getTheReceiver();
SEL request = getTheSelector();
[helper performSelector:request];

The Target-Action Design Pattern


在处理用户界面控制时,Appkit对于可变消息和可变接收对象运用的很好。例:
[myButtonCell setAction:@selector(reapTheWind:)];
[myButtonCell setTarget:anObject];

几个方法:
1. SEL val = @selector(method);
2. SEL val = NSSelectorFromString(methodString)
3. NSString *methodString = NSStringFromSelector(sel_val)

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics