`
sogotobj
  • 浏览: 652261 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

选择器

 
阅读更多

本文档版权归NickTang所有,没有本人书面或电子邮件允许,不许转载,摘录,发表。多谢!

在Objective-C语言中, 选择器(selector)有两层含义,在源代码中,它指代一个函数名称,在编译期间,它被一个唯一的标记符替代。编译后的选择器被替换成一个SEL类型. 所有具有同一个名称的函数具有同一个选择器。你可以使用选择器调用一个对象的方法--这是Cocoa中的目标-动作设计模式的最基本实现方式。

函数和选择器

为了效率,编译后的代码不再使用函数名称。作为替代,编译器把所有的函数名称保存在一个表中,然后为每一个函数名称声称一个唯一的标识,并在运行的时候使用这个标识作为函数的替代。运行环境包装每一个标识是唯一的:同样名称的函数具有相同的选择器,不同的函数的选择器绝对不同。

SEL和@selector

编译后的选择器使用一个特别的类型,SEL,以区别与其他数据类型。你必须使用一个函数来付值给一个SEL变量。@selector()指示在编译期间的选择器。下面的例子演示了使用函数setWidth:height:来付值给SEL类型的变量setWidthHeight:

SEL setWidthHeight;
setWidthHeight = @selector(setWidth:height:);

在编译期间,使用@selector()来直接设置SEL变量是很有效的。但是,有些情况下,你可能需要在运行期间使用一个字符串来转换成一个选择器,这个时候,你需要使用NSSelectorFromString函数:

setWidthHeight = NSSelectorFromString(aBuffer);

相反方向的转换也是有可能需要的。函数NSStringFromSelector就是做这个事情的:

NSString *method;
method = NSStringFromSelector(setWidthHeight);

函数和选择器

编译后的选择器指代函数的名称,而不是函数的实现。例如,一个类中的displa函数在其他类中可能有一个相同名字的函数,那么这就是多态性和动态绑定的本质;它可以让你对不同的类发送相同的消息。如果每一个函数的实现都不同,那么一个消息可能会有不同的函数调用。

具有相同名称的类函数和实例函数具有相同的选择器。但是,由于它们在不同的作用域中,所以这两种情况不会找出冲突,一个类可以拥有一个display实例函数的同时拥有一个display类函数。

函数的返回类型和参数类型

消息必须通过选择器才能转化为对函数实现的调用,因此一个消息对所有的相应的函数都会作为相同的选择器使用。消息通过选择器来了解函数的参数类型和返回类型。故此,除了是接受者是静态指定的,动态绑定需要所有的同一个名字的函数必须具有相同的函数类型和返回类型。(由于编译器会对静态接受者进行检查,所以它是这个规则的一个例外)

虽然相同的类方法和实例方法是有同一个选择器,但是它们可以有不同的参数类型和返回类型。

运行期验证消息

定义在类NSObject中的函数performSelector:performSelector:withObject:performSelector:withObject:withObject:使用一个SEL作为参数。这三个函数最后都转换为相应的函数调用,例如:

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

和下面的代码相等:

[friend gossipAbout:aNeighbor];

这三个函数使得在运行期对消息和消息接受者验证称为可能,并且在消息的任何部分都可以使用变量:

id   helper = getTheReceiver();
SEL  request = getTheSelector();
[helper performSelector:request];

在上面的例子中,接收者(helper)是在运行期决定的 (通过函数getTheReceiver调用决定), 并且接受者的函数(request)也是通过运行期决定的。

注:performSelector:等一干函数返回一个id类型的变量。如果函数返回一个其他的类型,必须通过转换来变成合适的方式(当然,不是所有的类型都能被转换,函数应该返回一个指针或者相似的类型)。


避免消息错误

如果一个接受者接到一个不在函数列表中的消息,就会发生一个错误。这个错误和调用一个不存在的函数的错误一样。不过由于消息是在运行期发生的,所以这个错误直到程序运行的时候才会发生发生。

这个错误在接受者和消息都是固定的时候是很容易避免的。由于是你写的程序,所以你可以保证接受者是能够对消息做出响应的。如果接受者是固定的,那么编译器可以为你做这样的检测的。

不过,如果消息接受者和消息本身是动态的,那么这个检验工作就要推迟到运行期了。定义在NSObject类中的函数respondsToSelector:就是为了测试一个接受者是否响应某个消息。它接受一个函数选择器作为参数,返回接受者能否响应这个选择器:

if ( [anObject respondsToSelector:@selector(setOrigin::)] )
    [anObject setOrigin:0.0 :0.0];
else
    fprintf(stderr, "%s can’t be placed\n",
        [NSStringFromClass([anObject class]) UTF8String]);

respondsToSelector:所作的运行期检测是很重要的,特别是你发消息到不是你所控制的类中的时候。例如,你发送一个消息到一个可以通过变量设置的接受者得时候,你必须通过这个函数来确认接受者是否实现了这个函数。

注:一个对象可以前转一个消息到其他的接受者,对于消息的发送方看到的是这个对象处理了这个消息。前参考Objective-C Runtime Programming Guide中的 “Message Forwarding”

分享到:
评论

相关推荐

    web端 日期选择器 月份选择器 时间选择器 时间范围选择器

    本文将详细讲解"web端日期选择器、月份选择器、时间选择器以及时间范围选择器"这四个核心知识点,并结合提供的文件名称进行分析。 1. **日期选择器** 日期选择器是Web应用中常见的组件,用于让用户选择一个具体的...

    基于jquery的H5移动端选择器,日期选择器,自定义级联选择器,自定义html选择器

    例如,在一个国家/地区选择器之后,可能会有一个相应的城市选择器,城市列表根据之前选择的国家动态加载。级联选择器提高了数据输入的效率,减少了用户输入的复杂性,同时也能够有效地管理大量数据。 自定义HTML...

    Android地名选择器 全国省市区选择器 城市选择 区县选择

    "Android地名选择器 全国省市区选择器 城市选择 区县选择"是一个针对这种需求的专业组件,它允许用户在应用程序内方便地挑选中国境内的省份、城市以及区县。这个组件通常包含一个层次化的列表视图,用户可以逐级下拉...

    城市选择器模块 城市选择器模块

    城市选择器模块城市选择器模块城市选择器模块城市选择器模块城市选择器模块城市选择器模块城市选择器模块城市选择器模块城市选择器模块城市选择器模块城市选择器模块城市选择器模块城市选择器模块城市选择器模块城市...

    数据选择器_数据选择器_

    数据选择器是一种数字逻辑电路,通常用于在多个输入信号中选择一个特定的信号输出。在VHDL(Very High Speed Integrated Circuit Hardware Description Language)中,我们可以编写代码来描述这种功能,以便在 FPGA...

    CSS选择器.pdf

    接下来是关系选择符,包括后代选择器、直接子元素选择器、相邻选择器、兄弟选择器和并列选择器。后代选择器(EF)用于选中某个元素(E)内部的所有指定元素(F),不论层级深浅。直接子元素选择器(E>F)则只选中...

    JSoup CSS选择器用法大全

    - `E ~ F`: 选择器 `E` 后面跟着一个或多个选择器 `F` 的元素,但不是紧邻的同级元素。 在爬虫开发中,利用这些 CSS 选择器,可以精准地定位到目标网页上的特定元素,从而提取所需信息。例如,`a[href^='http:']` ...

    实现了Android开发自定义年月日日期选择器,时分时间选择器

    本话题主要探讨如何实现自定义的年月日日期选择器和时分时间选择器,这两个组件在许多应用程序中都非常常见,例如在事件安排、预约服务或者设置提醒等功能中。 首先,我们来看如何创建自定义的年月日日期选择器。这...

    H5移动端选择器,layPicker移动端日期选择器

    在移动应用开发中,UI组件的选择器是必不可少的一部分,它们为用户提供友好的交互方式,比如日期选择、级联选择等。`layPicker`是一个专为移动端设计的jQuery选择器插件,尤其适用于微信环境和一些老旧版本的浏览器...

    HTML颜色选择器

    在给定的部分代码中,我们可以看到一个简单的颜色选择器实现方式: 1. **使用`<object>`标签引入外部组件**:代码中的`<object>`标签加载了一个名为`dlgHelper`的对象,这个对象可能是用来创建颜色选择对话框的...

    android 时间选择器

    在Android开发中,时间选择器(DatePicker)是一个常见的组件,用于让用户方便地选取日期或时间。本项目仿照苹果iOS的界面设计,提供了一个自定义的时间选择器,允许开发者进行高度自定义,如修改背景、字体等样式。...

    最新的省份选择器(中国)

    在中国的Web开发中,一个“省份选择器”是常见的组件,尤其在涉及到用户输入地理位置信息时。这个最新的省份选择器提供了高效且兼容性良好的解决方案。本文将深入探讨这个选择器的特点、实现方式以及如何在项目中...

    时间选择器(高仿ios就寝时间选择器)

    在本案例中,我们关注的是一个名为“时间选择器(高仿ios就寝时间选择器)”的组件,其设计灵感来源于iOS系统的就寝时间选择器。这个组件通常用于健康管理、睡眠追踪或定时提醒等应用程序,帮助用户方便地设定入睡和...

    基于Qt自定义的滑动选择器

    **基于Qt自定义的滑动选择器** 在软件开发中,UI界面的用户体验往往起着至关重要的作用。Qt是一个跨平台的应用程序开发框架,广泛应用于桌面、移动和嵌入式设备。它提供了一系列丰富的控件,帮助开发者创建美观且...

    layui多选级联选择器

    在layui中,级联选择器是一种常用于数据层级关系展示和选择的组件,尤其适用于地区选择、部门结构等场景。本篇文章将深入探讨layui的多选级联选择器及其无限级联功能。 首先,我们要理解什么是级联选择器。级联选择...

    WPF颜色选择器

    **WPF颜色选择器** 在Windows Presentation Foundation (WPF) 中,颜色选择器是一个非常有用的控件,允许用户直观地选取所需的颜色。WPF的颜色选择器通常被用于UI设计,以便用户可以自由调整应用程序界面的颜色或者...

    重新实现的Qt颜色选择器

    【标题】:“重新实现的Qt颜色选择器”深入解析 在Qt框架中,`QColorDialog`是一个重要的组件,用于创建一个用户界面,允许用户选择颜色。本篇将详细探讨如何重新实现这个颜色选择器,以及它在实际开发中的应用。 ...

    八选一数据选择器报告

    【八选一数据选择器】是一种数字逻辑器件,它能够从八个不同的数据输入中选择一个输出,选择由一组控制信号决定。在这个实验中,我们利用 Verilog HDL 语言来设计和实现了一个八选一数据选择器。Verilog 是一种硬件...

    数据选择器及其应用

    "数据选择器及其应用" 数字逻辑是计算机科学和技术的核心组成部分,掌握数字逻辑电路的设计步骤、分析方法和测试方法对于电子工程师和计算机科学家来说是非常重要的。本文将详细介绍数据选择器的工作原理、逻辑功能...

Global site tag (gtag.js) - Google Analytics