iOS学习笔记之回调(一)
什么是回调
看了好多关于回调的解释的资料,一开始总觉得这个概念理解起来有点困难,可能是因为自己很少遇到这种类型的调用吧。探索良久之后,才算有点启发,下面是自己的一点理解。
我们知道,在OSI网络七层模型中,上层可以直接调用下层的代码来为自己服务,这种调用是一种直接调用的方式。但是下层不能直接调用上层的代码,除非上层为下层提供了相应的函数。如果上层为下层提供了相应的函数,那么这个函数就被称为回调函数,下层通过回调函数调用上层的这种方式就是一种“回调”。
我们假定下图中的A代表应用层,B代表操作系统层,那么下图中的流程是:
step1:应用层A首先调用操作系统层B的代码,然后假定应用层A在等待操作系统层B的某个资源,为了让B在资源就位的时候可以通知A,A为B提供了一个函数(假定名为f)
step2:当A等待的资源就位时,B就可以调用函数f来通知A
在这个过程中,A设计了回调函数f,但实际调用回调函数的是B。事实上,A和B可以是同一个对象,为了便于理解和叙述,我们可以将两个实体分开来看。

回调主要的应用场景是:当前运行的应用在等待某个特定的事件,如鼠标移动、触摸事件等,当特定的事件发生后,需要通过某种方式告知正在等待的这个应用。
iOS中的回调
iOS中有三种方式可以实现回调
1、目标-动作
在应用等待前,要求当等待的特定事件发生时,向指定的对象发送某个特定的消息。接收消息的对象是目标,消息的选择器是动作。
2、辅助对象
在应用开始等待前,要求当等待的特定事件发生时,向遵守相应协议的辅助对象发送消息。委托对象和数据源是常见的辅助对象。
3、通告
苹果中有一种称为通告中心的对象。在应用开始等待前,可告知通知中心,某个对象正在等待特定的消息。当应用等待的特定事件发生时,相关的对象会向通知中心发布通告,然后再由通知中心将通告转发给正在等待该通告的对象。
目标-动作对
目标-动作是实现回调的一种较为简单的方式。对上图中的例子来讲,目标就是接收消息的对象,就是在等待某个特定事件的那个对象,因此A是B的目标,而动作就是那个回调函数,因此是A设计的f函数。
选择器
在继续讨论回调前,先简单介绍一下选择器。在iOS中,当某个对象收到消息时,会向该对象的类进行查询,检查是否有与消息名称匹配的方法。该查询过程会沿着继承层次结构向上,直到在某个类中查询到或到达继承的顶层。在查询过程中,要求查询的速度非常快速。如果使用方法的实际名称(可能会很长)进行查询,那么查询速度会很慢。因此,编译器会为每个其接触过的方法附带一个唯一的数字。在实际运行过程中,使用这个数字而不是方法名来查询。这个唯一的数字就成为选择器。通过编译指令@selector,可以得到与方法名相对应的选择器。
为了更加清晰的理解目标-动作对的机制,我们以一个简单的案例来分析。在下面的案例中,我们创建一个拥有NSRunLoop对象和NSTimer对象的应用。每隔2秒,NSTimer对象会向其目标发送指定的动作消息。同时,创建一个类,该类的实例设置为NSTimer对象的目标,如下图所示。

创建的代码如下:
首先创建Logger类作为NSTimer类的目标,在头文件中声明一个sayOuch函数。
Logger.h
@interface Logger : NSObject
- (void)sayOuch:(NSTimer *)t;
@end
在.m文件中实现sayOuch方法,让其在控制台输出一句话,便于观察方法运行结果。
Logger.m
@implementation Logger
- (void)sayOuch:(NSTimer *)t
{
NSLog(@"Ouch!");
}
@end
接下来在main函数中声明两个对象,分别是Logger类的对象logger,和NSTimer类的对象timer。我们把logger对象设置为timer对象的目标。
main
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
Logger *logger = [[Logger alloc] init];
NSTimer *timer = [NSTimer
scheduledTimerWithTimeInterval:2.0
target:logger
selector:@selector(sayOuch:)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] run];
}
return 0;
}
上述代码中,Logger类设置的函数sayOuch将被NSTimer对象调用,因此这个sayOuch函数就是一个回调函数。对照到A-B那个图来说,这个案例中的NSTimer类是B,它位于下层,而Logger类是上层,它提供了回调函数给下层调用。
总结
在iOS编程中,目标-动作对这种回调方式对用于UI控制器和UI控件之间,这种机制产生的原因是,某些事件不能确定何时发生(例如某个按钮被点击),但是一旦发生之后,就要按照预先定义的回调函数去处理。
iOS学习笔记之回调(一)的更多相关文章
- iOS学习笔记之回调(二)
写在前面 上一篇学习笔记中简单介绍了通过目标-动作对实现回调操作:创建两个对象timer和logger,将logger设置为timer的目标,timer定时调用logger的sayOuch函数.在这个 ...
- ios学习笔记block回调的应用(一个简单的例子)
一.什么是Blocks Block是一个C级别的语法以及运行时的一个特性,和标准C中的函数(函数指针)类似,但是其运行需要编译器和运行时支持,从ios4.0开始就很好的支持Block. 二. ...
- iOS学习笔记10-UIView动画
上次学习了iOS学习笔记09-核心动画CoreAnimation,这次继续学习动画,上次使用的CoreAnimation很多人感觉使用起来很繁琐,有没有更加方便的动画效果实现呢?答案是有的,那就是UI ...
- IOS学习笔记48--一些常见的IOS知识点+面试题
IOS学习笔记48--一些常见的IOS知识点+面试题 1.堆和栈什么区别? 答:管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制:对于堆来说,释放工作由程序员控制,容易产生memor ...
- iOS学习笔记16-数据库SQLite
一.数据库 在项目开发中,通常都需要对数据进行离线缓存的处理,如新闻数据的离线缓存等.离线缓存一般都是把数据保存到项目的沙盒中.有以下几种方式: 归档:NSKeyedArchiver 偏好设置:NSU ...
- iOS学习笔记13-网络(二)NSURLSession
在2013年WWDC上苹果揭开了NSURLSession的面纱,将它作为NSURLConnection的继任者.现在使用最广泛的第三方网络框架:AFNetworking.SDWebImage等等都使用 ...
- iOS学习笔记——AutoLayout的约束
iOS学习笔记——AutoLayout约束 之前在开发iOS app时一直以为苹果的布局是绝对布局,在IB中拖拉控件运行或者直接使用代码去调整控件都会发上一些不尽人意的结果,后来发现iOS在引入了Au ...
- IOS学习笔记25—HTTP操作之ASIHTTPRequest
IOS学习笔记25—HTTP操作之ASIHTTPRequest 分类: iOS2012-08-12 10:04 7734人阅读 评论(3) 收藏 举报 iosios5网络wrapper框架新浪微博 A ...
- IOS学习笔记之关键词@dynamic
IOS学习笔记之关键词@dynamic @dynamic这个关键词,通常是用不到的. 它与@synthesize的区别在于: 使用@synthesize编译器会确实的产生getter和setter方法 ...
随机推荐
- z-index无效问题的解决方法
在使用z-index这个属性之前,我们必须先了解使用z-index的必要条件: 1.要想给元素设置z-index样式,必须先让它变成定位元素,说的明白一点,就是要给元素设置一个postion:rela ...
- jquery ajax json简单的分页,模拟数据,没有封装,只显示原理
简单的分页,模拟数据,没有封装,显示原理,大家有兴趣可以自己封装,这里只是个原理过程,真正的分页也差不多是这个原理,只是请求数据不太一样,html部分: <!TOCTYPE HTML> & ...
- USACO Section 2.3: Money Systems
简单的dp题 /* ID: yingzho1 LANG: C++ TASK: money */ #include <iostream> #include <fstream> # ...
- Ubuntu下安装Git以及Git帮助手册【转】
转自:http://milkythinking.com/blog/2011/04/17/install_git_and_manual/ Git简介 Git是一个分布式版本控制系统,对应的是SVN.CV ...
- linux目录
转自:http://www.educity.cn/it/linux/201002040848221715.htm 对于linux新手来说,最感到迷惑的问题之一就是文件都存在哪里呢?特别是对于那些从wi ...
- java-基础练习题1
/** 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,* 假如兔子都不死,问每个月的兔子总数为多少?* 1.程序分析: 兔子的规律为数列1, ...
- 适用于Firemonkey的Json解析对象XsuperObject使用方法介绍
XSuperObject是适用于FileMonkey平台的JSON解析组件,能够在Android,IOS,MACOS,WINDOWS等多个平台使用 点击下载 Sample JSON { "n ...
- 51nod1225 余数之和
打表可以看出规律.分块求就可以了. #include<cstdio> #include<cstring> #include<cctype> #include< ...
- Web程序员最常用的11款PHP框架
PHP框架是Web程序员和开发人员最为有用的工具. PHP框架可以帮助用户更快地开发项目. 今天我将为开发人员带来几款最好的PHP框架,希望能对你有用. 1.Agavi Agavi是一款强大的,可扩展 ...
- Matlab---size,length和numel函数的用法
size:获取数组的行数和列数 length:数组长度(即行数或列数中的较大值) numel:元素总数. 1.size()函数 s=size(A),当只有一个输出参数时,返回一个行向量,该行向量的第一 ...