1、Block 本质上是一个struct结构体,在这个结构体中,最重要的成员是一个函数(当然除函数外还有其他重要的成员)。

2、在开始解析Block之前,首先来回顾一下Block的格式。Block相关的格式有2个:

(1)、Block对象的格式;

(2)、Block变量的格式;

3、对于Block对象,它有几种常见的格式:

(1)、一个完整的Block对象的格式如下:

比如这个Block对象:

可以发现,完整的Block对象和函数的定义非常相似,比如这个函数:

两者之间的区别仅仅是:Block对象多了一个“^”符号,并且不需要像函数一样指定函数名;

(2)、在完整的格式中有一些项目是可以省略的,比如“返回值类型”。不管Block对象是否有返回值,这个项目都是可以省略的,省略之后,只要表达式中有return语句就会自动使用该返回值的类型,如果没有return语句就会使用void类型。

在这种情况下,Block对象的格式就变成了:

所以上文(1)中的Block对象可以写成这样:

(3)、除此之外,如果Block对象不需要参数的话,那么“参数列表”这个项目也是可以省略的,这时候Block对象的格式就变成了:

比如这样的一个Block对象:

4、定义了Block对象之后,还要定义Block变量来持有它,才能更方便地使用Block对象。回顾一下3(1)的函数:

对于这种函数,可以声明这样一个函数指针类型变量来使用它:

这时使用*funcPtr的就相当于在使用func函数了。

同样的,对于3(1)中的Block对象,也可以声明这么一个Block变量:

这时使用block()的时候就相当于在使用这个Block对象了。

对比函数指针和Block变量的声明,可以发现两者也是非常相似的,区别仅仅是将*号换成^

5、如果要将Block变量当做参数来传递的话,每次使用都完整地定义它显然是很麻烦的事。比如想要在一个函数里使用Block变量类型的参数,完整的定义方式应该是这样的:

这显然是很繁琐的,这时候就可以通过typedef来简化变量:

那么这个函数就可以定义成:

这时就可以非常方便地使用Block变量了。

6、回顾完Block 相关的格式,接下来开始来讨论Block的实现。

在前文提到过,Block最重要的组成部分是一个函数,这也就意味着,大部分Block能实现的功能,其实使用函数也可以实现的。接下来就先来试一试要如何在不使用Block的情况下实现Block的功能。

思考这么一个问题:假设有两个按钮button1和button2,要求实现以下功能:

(1)、按钮有编号;

(2)、编号可修改;

(3)、点击按钮输出自己的编号。

7、首先简单的方法可以通过使用两个函数来实现:

两个函数分别对应两个按钮的点击,调用函数时把按钮的编号作为参数传进去,便能打印出对应编号。

看起来似乎能满足功能了,但是这种方法的问题也是很明显的:按钮并不持有自己的编号,需要调用函数的时候才将编号传进去。

这种方法显然还不够完善。

8、根据面向对象的思考方式,通过将按钮抽象成类并把编号定义成按钮类的实例变量是可以实现这个功能的。但是这里只想要使用普通C语言来实现,那么可以这么处理,把每个按钮的编号定义成全局变量来进行保存,修改的代码如下:

这样按钮就“持有”了编号,实现了问题的3个要求。

9、回过头来看一看问题,如果要使用Block来实现这3个要求的话,代码会是这样的:

这段代码所实现的功能,和8的代码所实现的功能其实就是一样的了。

10、事实上,这两段代码几乎就是等价的了,8的代码几乎就是9的代码转换成普通C语言后的样子(注意“几乎”这个字眼,实际上5的代码转换成普通C语言后与4的代码还是有不少差别的)。

而对于问题中所提的3个要求,其实就是Block的3个主要功能点:

(1)、能截获变量;

(2)、能截获可变的变量;

(3)、回调。

格而知之15:我所理解的Block(1)的更多相关文章

  1. 格而知之3:Core Data的基本使用

    最近准备做一个随手笔记类的app给自己用,考虑到从未使用过Core Data,就决定用Core Data来做数据存储.在网上参考了一些Core Data的资料后,用一天的时间写了这个demo,主要测试 ...

  2. PHP程序员应该知道的15个库

    最几年,PHP已经成为最受欢迎的一种有效服务器端编程语言.据2013年发布的一份调查报告显示,PHP语言已经被安装在全球超过2.4亿个网站以及210万台Web服务器之上.PHP代表超文本预处理器,它主 ...

  3. 格而知之16:我所理解的Block(2)

    11.那么Block到底是怎么实现的呢?试一试通过将Block 的代码转换成普通C语言代码来查看它的实现过程. 要将OC代码转换成C语言代码,可以使用clang编译的一个命令: 通过这个命令能把指定文 ...

  4. 格而知之8:我所理解的Runtime(3)

    关联对象 14.使用Category对类进行拓展的时候,只能添加方法,而不适合添加属性(可以添加属性,也可以正常使用get方法和set方法,只是不会自动生成以下划线开头命名的成员变量). 可以通过关联 ...

  5. 格而知之6:我所理解的Runtime(1)

    基本简介 1.根据官方文档,OC有一个特性:它会尽可能把一些决定从编译时和链接时推迟到运行时才处理,所以这门语言需要的就不只是一个编译器,它还需要一个runtime系统来处理那些已经被编译过的代码. ...

  6. 格而知之16:我所理解的Block(3)

    23.在前文中的例子中,Block结构体里的isa指针还没有详细讲解,这个指针都被置向了_NSConcreteStackBlock,它标识了Block的类型. 其实除了_NSConcreteStack ...

  7. 格而知之7:我所理解的Runtime(2)

    消息发送(Messaging) 8.以上便是runtime相关的一些数据结构,接下来我们回看一开始的疑问: objc_msgSend()函数在执行的过程中是如何找到对应的类,找到对应的方法实现的呢? ...

  8. 格而知之5:我所理解的Run Loop

    1.什么是Run Loop? (1).Run Loop是线程的一项基础配备,它的主要作用是来让某一条线程在有任务的时候工作.没有任务的时候休眠. (2).线程和 Run Loop 之间的关系是一一对应 ...

  9. 每个php程序员都应该知道的15个最佳PHP库

    PHP是一种功能强大的web站点脚本语言,通过PHP,web网站开发者可以更容易地创建动态的引人入胜的web页面.开发人员可以使用PHP代码与一些网站模板和框架来提升功能和特性.然而,编写PHP代码是 ...

随机推荐

  1. Cocos2d-x学习笔记(3)

    Cocos2d-x有一个包括全部其它头文件的cocos2d.h,仅仅要在使用时包括这个头文件,就能够使用引擎的全部功能.Cocos2d-x的类都放置于cocos2d的命名空间下,如引擎下的" ...

  2. 标准I/O介绍

    标准I/O库 1. 标准I/O介绍 不仅是在UNIX系统中,很多操作系统上都实现了标准I/O库. 标准I/O库由ANSI C 标准说明 标准 I/O 库处理很多细节,例如带有缓冲分配.以优化长度执行的 ...

  3. C#工厂模式代码实例

    此处示例为一个简易计算器工厂模式的实现. 创建类库,名为CalcLib,我把计算功能全部放在这个类库中. 首先,创建一个抽象的计算器算法父类,如下: /// <summary> /// 计 ...

  4. UVA10305 拓扑排序

    网址:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=117863#problem/B 思路分析:裸的拓扑排序,注释在代码中. 代码: #i ...

  5. mongodb内嵌文档的查询

    本文转自:http://blog.163.com/wm_at163/blog/static/1321734902012526103825481/ 1 > db.blog.findOne() { ...

  6. Mysql存储过程分析

    为了搞明白为什么mysql的存储过程是高效的,我们需要理解mysql的执行流程是什么,当输入sql语句之后,mysql会先进行sql语句语法正确性检查,然后再进行编译,然后才执行,最后把结果返回.如下 ...

  7. Bootstrap定制(二)less基础语法

    前几日花了一天去看less,这几日在捣鼓其他东西,项目也在有序的进行中,今天花点时间整理下less的基础语法,也分享实际中的一些经验,与众人共享. 本篇笔者以less的基础语法着手,并配合bootst ...

  8. js页面加载进度条(这个就比较正式了,改改时间就完事儿)

    不废话,直接上代码 思路不难,就是一个animate方法配合随机数 duration内个三秒钟,是自定义的,可以改成页面加载时间,这样就完美了 <!doctype html> <ht ...

  9. mysql和mysqli的区别

    看书.看视频的时候一直没有搞懂mysqli和mysql到底有什么区别.于是今晚“谷歌”一番,整理一下.需要的朋友可以参考下.   一: PHP-MySQL 是 PHP 操作 MySQL 数据库最原始的 ...

  10. CSS的一些思考(一)

    迈入前端行业已经8个多月了,从之前懵懵懂懂到现在的能根据设计图迅速成型页面,自我感觉良好.最近看到张大牛的一篇博客<说说CSS学习中的瓶颈>,突然意识到,自己不就处在快速学习和成长后的一个 ...