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. [原创作品] RequireJs入门进阶教程

    最近我发现RSS采集数据是个很好玩的东西,就是可以直接把别人的数据放在自己的网站上.如果网友们在其他地方发现这篇文章,还是来博客园看吧(http://zhutty.cnblogs.com).这样代码比 ...

  2. Android-67-Tomcat启动出错:Server Tomcat v7.0 Server at localhost failed to start.

     错误:Server Tomcat v7.0 Server at localhost failed to start.如图: 唉! ! !!图片上传不上去,悲哀啊!..仅仅能先写着错误提示语吧~~ ...

  3. Ubuntu 14.04根据系统,休眠后不能启动要解决的问题

    简介: 提升Ubuntu制度14.04之后,当系统进入休眠,我们不能再次启动,直接崩溃,凡出了问题? 1.   问题纳入 Ubuntu升级系统14.04之后.通过系统的Power设置休眠时间,在系统进 ...

  4. mogodb亿万级数据性能測试

    本机 i7四核 8G 废话少说 mogodb 最像sql的nosql 使用批量插入一次20万循环10次总共200万数据用时65秒(尝试一次50万只是报内存溢出了,原因未知) 插入2000万数据用时10 ...

  5. 常用SQL语句学习整理

    增 insert into table_name (column_name1,column_name2) values (value1,value2) 删 delete from table_name ...

  6. Light oj 1030 二分查找

    1088 - Points in Segments   PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 ...

  7. (原)10-folder交叉验证

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/6069731.html 参考网址: https://github.com/cmusatyalab/ope ...

  8. winPcap_1_开篇

    什么是WinPcap WinPcap是一个基于Win32平台的,用于捕获网络数据包并进行分析的开源库. 因为有些应用程序需要直接访问网络中的数据包.也就是说,那些应用程序需要访问原始数据包,即没有被操 ...

  9. 虚拟机安装centos

    linux安装 鉴于国内大多数服务器都使用的redhat系列作为操作系统,centos又是redhat的免费版本,所以可以学习一下.因为另一台古董电脑已经装了linuxmint,虽然也可以安装虚拟机, ...

  10. jade的基本语法

    - for (var i=0;i<3;i++) li scnu-learn //这里的=,默认会转义内容 p= "Welcome scnu <strong>good< ...