什么是回调?

因为它是从C开始进入编程世界。术语改只是口。叫习惯了。java里通常叫listener(监听器)。C/C++里通常叫callback(回调),ObjC里面叫delegate(托付)

回调就是调用事先设置一个上下文数据(它可能是某个消息值,可能是某个函数。可能是某个对象)到某个负责处理数据的对象或者代码里。

然后開始运行这个处理过程,这个处理过程处理完了之后。会依据处理的结果将之前设置的相应的上下文数据反馈给你。

举个样例吧。比方我有个函数是下载一个http的图片资源。

在调用这个函数之前,我先告诉这个函数。假设下载成功了。你就给我发一个通知1,假设失败了,就给我发一个通知0(当然是返回0,1最简单啦。可是假设是异步的呢)。回调的形态多种多样。各种方式的都有,可是本质上就是一个模块的代码通知告知还有一个模块某个结果,某个状态。某个进度。

C语言里面,因为仅仅有函数。没有对象。所以C语言的回调经常使用两种:1、消息通知。2、回调函数。

对于消息通知来说。须要一个消息循环。

当进入某个状态或者处理完某个人物的时候,发送一个通知到消息循环,在负责处理的地方。等待这个消息就能够了。

实际开发中用到消息循环的地方有:win32API/MFC 的消息机制,android的handler机制,都是消息回调方式。

对于函数回调来说。运行A函数的时候。函数參数里传入S函数和F函数的指针,假设A运行成功了。最后在A里面调用S,假设A运行失败了。在最后A里面调用F。

比方C里面的回调大概就是以下这种。

void S()
{}
void F()
{} typedef (void*)() callback ;
void A(callback s, callback f)
{
if(成功)
s();
else
f();
}

C进化到C++之后,回调的方式就好多了,由于有对象了。管理对象总是比管理单个函数方便的多,由于对象能够同一时候关联函数和数据。

比方C++ 对象方式的回调样子大概像以下这样

struct CPPCallback
{
virtual void callbackFunctionS();
virtual void callbackFunctionF();
} void A(CPPCallback* calback)
{
if(成功)
calback-> callbackFunctionS();
else
calback-> callbackFunctionF();
}

使用对象指针回调会方便非常多,由于CPPCallback一般是纯虚类,由实际场景中的某个类来实现。而且对象指针回调更加符合面向对象的模式,越是高级的语言。越面向对象,假设和这个趋势相违背,那势必用起来是不那么方便的。C++同一时候也能够使用C的回调方式,就不在举例了。

java的回调方式。是依照 触发器 +监听器的理念设计的。本质和C++那个没什么差别。叫法不一样。

interface JavaListener
{
public void callbackFunctionS();
public void callbackFunctionF();
} void A(JavaListener listener)
{
if(成功)
listener.callbackFunctionS();
else
listener.callbackFunctionF();
}

java官方的代码以及开源码里面,一般出现的都是这样的回调方式(android handler那种除外),java全然面向对象所以不会出现单独的函数回调。

监听器 + 触发器的叫法,我个人是很喜欢的。

以至于个人在开发 C++代码,ObjC代码,其它全部语言的程序的时候,都沿用了Java里面的叫法。特别是ObjC的托付授权叫法。实在是拗口,不好理解。

ObjC的回调方式。官方的叫法叫托付(delegate)。可是ObjC的回调的详细形式却非常灵活,因为ObjC也面向对象,所以它肯定能够支持java这样的回调。

可是ObjC还支持一种 对象指针 +函数名的轻量级回调,后者在代码书写量上面。反而要简单很多。

比方ObjC中类似java的那种回调方式

@protocol XXXXDelegate <NSObject>
-(void) callbackFunctionS;
-(void) callbackFunctionF;
@end -(void)A:(id<XXXXDelegate>)delegate
{
if(成功)
[delegate callbackFunctionS];
else
[delegate callbackFunctionF];
}

ObjC另外一种更简单的回调。另外一种回调不用定义protocol

@class-implemention SomeClassA //如果某个类的实现文件

-(void) callbackFunctionS
{
}
-(void) callbackFunctionF
{
} -(void)A:(id)delegate withS:(SEL)funS withF:(SEL)funF
{
if(成功)
[delegate performSelector:funS withObject:nil];
else
[delegate performSelector:funF withObject:nil];
} -(void)callA //演示调用A的情况
{
[self A:self withS:@selector(callbackFunctionS) withF:@selector(callbackFunctionF)];
} @end

仅仅要调用A第一个參数传入的对象 delegate的类里面有名字叫callbackFunctionS和叫callbackFunctionF的函数就可以。

ObjC的类型 SEL,实际上就是一个 char*类型。它的原理是通过字符串去查找某个函数,然后再某个对象上运行这个函数。

主要的这三种语言的回调方式就是这种了,假设取长补短,其它语言借鉴一下思路,java语言里也能够实现ObjC的另外一种回调方式。

C++则比較麻烦,由于C++不直接支持反射。仅仅能通过类似微软的COM模式,模拟实现。微软的COM也是个不错的东西。火狐浏览器的底层架构。就是用的XPCOM(基于COM思路设计的)。

C++怎样反射。能够參考我的还有一篇文章。

java的反射机制。比ObjC更彻底,由于java是纯解释性语言。ObjC是半解释语言。

所以java实现ObjC另外一种回调方式,so easy!

完整代码例如以下:

package com;
import java.lang.reflect.Method;
public class Main2 { public static void main(String[] args) throws Exception{
new Main2().run();
} public void callbackFunctionS() {
System.out.println("callbackFunctionS");
}
public void callbackFunctionF() {
System.out.println("callbackFunctionF");
}
public void A(Object obj, String funcS, String funcF) throws Exception
{
Class clz = obj.getClass() ;
Method methodS = clz.getMethod(funcS, null);
Method methodF = clz.getMethod(funcF, null);
if(true) //成功
methodS.invoke(obj, null);
else
methodF.invoke(obj, null);
}
public void run() throws Exception{
this.A(this, "callbackFunctionS", "callbackFunctionF");
}
}

不同语言,不同平台湾。基本上相同的。好想法。设计理念可以学习。

版权声明:本文博主原创文章,博客,未经同意不得转载。

编程基础——C/C++,Java,ObjC讨论回调模式的更多相关文章

  1. java并发编程基础 --- 7章节 java中的13个原子操作类

    当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量 i=1,A线程更新 i+1,B线程也更新 I+1,经过两个线程的操作之后可能 I不等于3,而是等于2.因为A和B线程更 ...

  2. Java入门——(1)Java编程基础

    Java入门--(1)Java编程基础 第二章 Java编程基础   JAVA 代码的基本格式: 修饰符 class 类名{ 程序代码 }   2.1关键字:赋予了特殊含义的单词.   2.2标识符: ...

  3. Java开发知识之Java编程基础

    Java开发知识之Java编程基础 一丶Java的基础语法 每个语言都有自己的语法规范.例如C++ 入口点是main. 我们按照特定格式编写即可. Java也不例外. Java程序的语法规范就是 Ja ...

  4. (翻译)理解Java当中的回调机制

    原文地址:http://cleancodedevelopment-qualityseal.blogspot.com/2012/10/understanding-callbacks-with-java. ...

  5. Java网络编程和NIO详解开篇:Java网络编程基础

    Java网络编程和NIO详解开篇:Java网络编程基础 计算机网络编程基础 转自:https://mp.weixin.qq.com/s/XXMz5uAFSsPdg38bth2jAA 我们是幸运的,因为 ...

  6. Java并发编程--基础进阶高级(完结)

    Java并发编程--基础进阶高级完整笔记. 这都不知道是第几次刷狂神的JUC并发编程了,从第一次的迷茫到现在比较清晰,算是个大进步了,之前JUC笔记不见了,重新做一套笔记. 参考链接:https:// ...

  7. [Java入门笔记] 面向对象编程基础(二):方法详解

    什么是方法? 简介 在上一篇的blog中,我们知道了方法是类中的一个组成部分,是类或对象的行为特征的抽象. 无论是从语法和功能上来看,方法都有点类似与函数.但是,方法与传统的函数还是有着不同之处: 在 ...

  8. 如何夯实(Java)编程基础,并深入学习和提高

    如何夯实(Java)编程基础,并深入学习和提高? 240赞同反对,不会显示你的姓名 匿名用户 240 人赞同 多学习...网上自学的学习网站很多,见以下榜单~一.汇总榜单: 公开课_学习网站导航 收录 ...

  9. Java面向对象编程基础

    一.Java面向对象编程基础 1.什么是对象?Object 什么都是对象! 只要是客观存在的具体事物,都是对象(汽车.小强.事件.任务.按钮.字体) 2.为什么需要面向对象? 面向对象能够像分析现实生 ...

随机推荐

  1. Windows 10Bash命令

    Windows 10预览版14316开启Bash命令支持 00x0 前言 4月7日凌晨,微软推送了最新的Windows 10一周年更新预览版14316,其中重要的是原生支持Linux Bash命令行支 ...

  2. 【译】ASP.NET MVC 5 教程 - 11:Details 和 Delete 方法详解

    原文:[译]ASP.NET MVC 5 教程 - 11:Details 和 Delete 方法详解 在教程的这一部分,我们将研究一下自动生成的 Details 和Delete 方法. Details ...

  3. gdb学习(一个)[再版]

    概要 gdb是GNU debugger的缩写,是编程调试工具. 功能 1.启动程序,能够依照用户自己定义的要求随心所欲的执行程序. 2.可让被调试的程序在用户所指定的断点处停住 (断点能够是条件表达式 ...

  4. PHP实现栈(Stack)数据结构

    栈(Stack),是一种特殊的后进先出线性表,其只能在一端进行插入(插入一般称为压栈.进栈或入栈)和删除(删除一般称为弹栈.退栈或出栈)操作,允许进行插入和删除操作的一端称为栈顶,另一端则称为栈底.栈 ...

  5. Windows phone 8 学习笔记(4) 应用的启动

    原文:Windows phone 8 学习笔记(4) 应用的启动 Windows phone 8 的应用除了可以直接从开始菜单以及应用列表中打开外,还可以通过其他的方式打开.照片中心.音乐+视频中心提 ...

  6. C++ Primer笔记10_运算符重载_赋值运算符_进入/输出操作符

    1.颂值运营商 首先来福值运算符引入后面要说的运算符重载.上一节说了构造函数.拷贝构造函数:一个类要想进行更好的控制.须要定义自己的构造函数.拷贝构造函数.析构函数.当然,还有赋值运算符.常说的三大函 ...

  7. PowerDesigner 对 Oracle 作 逆向工程

    原文 PowerDesigner 对 Oracle 作 逆向工程 目的 PowerDesigner 15对OracleClient 11g进行逆向工程 环境 Win7 64位系统 Oracle 11g ...

  8. bnu1066

    hnu1066 给我们一张图,问我们摧毁边使得s和t不连通有多少种方案, 方案与方案之间不能存在相同的摧毁目标. 这是一个神奇的题目. 这题可以转为求s与t的最短路,为什么呢? 因为方案与方案之间不能 ...

  9. Shiro学习笔记(5)——web集成

    Web集成 shiro配置文件shiroini 界面 webxml最关键 Servlet 測试 基于 Basic 的拦截器身份验证 Web集成 大多数情况.web项目都会集成spring.shiro在 ...

  10. URAL 1728. Curse on Team.GOV(STL set)

    题目链接:space=1&num=1728" target="_blank">http://acm.timus.ru/problem.aspx?space= ...