理解 block
开始:Block 简介
Block 是 iOS 4.0 和 Mac OSX 10.6 引入的一个新特性。 Block 可以极大的简化代码。 他们可以帮助你减少代码, 减少对代理的依赖, 并且写出更加简洁,可读性强的代码。
即使有这么多好处, 还是有很多开发者没有使用 Block, 因为他们不知道如何使用。 但是 Block 绝对是你作为一个 Objective-C 程序员,一定会想要掌握的技能。
让我们来看看 Block 是谁, 是什么,在哪里用它, 为什么用它, 还有什么时候用它。
Block 是什么东西,它为什么那么重要?

Block 的核心就是一段可以在以后的时间里执行的代码。
Block 是 first-class functions, 也就是说 Block 是一个标准 Objective-C 对象。 因为他们是对象, 他们可以作为参数传递, 作为方法或函数的返回值, 赋值给变量。
在其他语言中,比如 Python,Ruby 和 Lisp, Block 又叫做闭包, 因为他们包含了定义时的状态。 Block 会为所有和它在同一作用范围内的局部变量创建一个常量拷贝。
在没有 Block 之前, 如果我们想在之后的某个时间回调一个方法, 你一般会用代理或者 NSNotificationCenter。 这样也不错, 除了一点,它会让你的代码到处都是 – 你在一个地方开启了一个任务, 然后在另外一个地方处理它的结果。
Block 是非常不错的, 因为它能将和一个任务相关的所有代码都放在一个地方, 你马上就会看到。
Block 为谁准备?
你! Block 是为每一个人准备的! 严格的说, Block 是为每个人和每个将要用到 Block 的人准备的。 Block 是未来的趋势, 所以你最好现在也学一下。 很多内建的方法已经用 Block 重写或者提供了接受 Block 参数的版本。
你怎样用 Block?
这张 iOS Developer Library 中的图片很好的解释了 Block 的语法:

Block 的声明格式如下:
return_type (^block_name)(param_type, param_type, ...) |
如果你之前使用过其他 C 类型的语言,那这段代码你应该看起来很眼熟, 除了这个 ^ 符号。 ^ 这个符号表示了 “我们定义的这个东西是一个 Block”。
如果你能分析到 ^ 符号的意思 “我是一个 Block” ,那么祝贺你 – 你已经了解了 Block 中最难的部分! :]
注意这里不需要参数的名称, 不过,如果你喜欢的话,你也可以加上它们。
下面是定义 Block 的一个例子:
int (^add)(int,int) |
下面是 Block 的定义格式:
// Block Definition |
这就是 Blcok 实际是怎么创建的。 Block 还有另外一种不同的定义方法。 以 ^ 符号起始,后面跟随着参数,这里的参数必须有参数名, 还必须和它要赋值到的 Block 声明中参数列表里面的参数类型和顺序相匹配。下面是实际的代码。
当你定义 Block 时, 返回值类型是可选的,并且可以继承它里面代码的返回值类型。 如果它里面有多条 return 语句,那么这些语句返回的类型必须都是相同的 (或者强制转换到相同的类型)。
这里是 Block 定义的一个例子:
^(int number1, int number2){ return number1+number2 }
|
如果我们将 Block 的声明和定义放在一起, 我们会得到这样一个语句:
int (^add)(int,int) = ^(int number1, int number2){
|
我们可以这样使用 Block:
int resultFromBlock = add(2,2); |
让我们看一看,使用 Block 和不使用 Block 之间对比的一些例子。
示例: NSArray
让我们看看 Block 如何改变我们操作数组的方式。
首先,让我们看一下一般情况下处理循环的方式:
BOOL stop; |
上面方法中的 “stop” 变量,可能会让你不太明白。 但是如果用 Block 的方式实现它,你就会很清楚的看明白了。 Block 提供了一个 “stop” 变量能让你在任何时候停止循环,我们简单的复制了这个功能来支持和 Block 的方式等同的效果。
现在,让我们看看用快速枚举的方法实现同样的功能:
BOOL stop; |
现在,用 Block:
[theArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){
|
在上面这个基于 Block 的代码中,你可能会好奇 “stop” 这个变量到底是什么。 这个变量可以在 block 中赋值为 YES, 这样就后续的任何循环都不会继续了。 这是传递到 enumerateObjectsUsingBlock 方法的 Block 中的其中一个参数。
上面这个例子有些微不足道, 而且也很难明显的体现出 Block 所到来的好处。 但是我想给大家指出 Block 的两点好处:
- 简单性. 使用 Block 我们可以不写任何附加的代码就可以访问对象,对象在数组中的索引,stop 变量。 这意味着少量的代码,减少了发生编码错误的机会(当然,并非我们一定会出现编码错误)。
- 速度. 使用 Block 在执行速度上要比使用快速枚举快。 在我们这个例子中,这点微小的速度提升不值得一提,但是在更复杂的情况下,这个优势就越来越重要。(来源)
示例: UIView Animation
让我们对一个单独的 UIView 执行一个简单的动画。 它将视图的透明度调整为 0,将这个视图向下和向右移动 50 点。 然后将这个 UIView 从它的 superview 中删除掉, 很简单,对吗?
非 Block 的实现方式:
- (void)removeAnimationView:(id)sender {
|
Block 的实现方式:
- (void)viewDidAppear:(BOOL)animated |
如果我们仔细看一看这两个方法, 就会发现有 3 个优势:
- 更简单的代码 使用 Block, 我们不再需要单独定义一个回调方法, 或者调用 beginAnimations/commitAnimations 。
- 保持代码在一起 使用 Block, 我们不再需要在一个地方开启动画,然后再另外一个地方处理回调。 所有和我们动画相关的代码都在一处, 这样让他的可读性和维护性更强。
- 苹果推荐这样 这里有一个现实的例子, 苹果已经用 Block 重写了之前的一些功能, 现在苹果官方也推荐,如果可能的话,尽量迁移到基于 Block 的方法上面。 (来源)
什么时候用 Blocks
我认为最佳的建议是, 在最合适用 Block 的地方使用它。 这里你可能会出于向后兼容或者更加熟悉以前的方式的原因,从而还要用老的方法。
但是每次你面临这种决策的时候, 想一想 Block 是否能让你更轻松以及你是否能用基于 Block 的方式代替现有代码。 然后选择一个对你最有价值的方法。
当然,你可能会发现,在以后的时间里, 你需要越来越多的使用 Block, 因为大多数框架,无论是第三方的还是苹果自己的,都正在用 Block 重写。所以为了让你未来更加轻松,现在就开始使用 Block 吧。
参考:http://www.raywenderlich.com/zh-hans/18753/如何在-ios-5-中使用-block-2
理解 block的更多相关文章
- 对于block的理解,block的面试题
1.block跟swift中的闭包(closure)基本一样,都常用于值的回调,特别是在多线程的网络请求回调中,使用起来极为方便. 2.block的开头是"^",接着是由小括号所报 ...
- 深入理解block
2010年WWDC发布iOS4时Apple对Objective-C进行了一次重要的升级:支持Block.说到底这东西就是闭包,其他高级语音例如Java和C++已有支持,第一次使用Block感觉满简单好 ...
- 理解block和inode
什么是block和inode? 定义:block就像是杯子 inode就像是杯子的编号,因为杯子太多了 1.根据文件的大小,在磁盘中储存时会占用一个或多个block:那么究竟多大的文件会使用一个blo ...
- 从汇编代码理解 Block 的内存结构
❓ 在断点调试 iOS 程序碰到 block 作为函数的形参时,如果想知道该 block 本身的函数签名信息和函数体地址时,有哪些办法?
- Block使用
1.对block的理解 > block是iOS4.0之后出现的,是仿照java中匿名函数所创造的,它是c级别的语法,效率比协议-代理高 > block的是一个匿名函数(没有名字的函数) ...
- 理解 Cinder 架构 - 每天5分钟玩转 OpenStack(45)
从本节开始我们学习 OpenStack 的 Block Storage Service,Cinder 理解 Block Storage 操作系统获得存储空间的方式一般有两种: 通过某种协议(SAS,S ...
- Block、委托、回调函数原理剖析(在Object C语境)——这样讲还不懂,根本不可能!
开篇:要想理解Block和委托,最快的方法是搞明白“回调函数”这个概念. 做为初级选手,我们把Block.委托.回调函数,视为同一原理的三种不同名称.也就是说,现在,我们把这三个名词当成一回事.在这篇 ...
- Block介绍(二)内存管理与其他特性
我们在前一章介绍了block的用法,而正确使用block必须要求正确理解block的内存管理问题.这一章,我们只陈述结果而不追寻原因,我们将在下一章深入其原因. 一.block放在哪里 我们针对不同情 ...
- Magento Block设计分析(深入分析)
Magento中Block是一个很重要的组件,它在Block中充当非常重要的角色,下面我们来分析一下Magento中Block是怎样设计的,我们应该怎样使用这个重要的角色. 1.Magento Blo ...
随机推荐
- centos下配置nginx支持php
添加nginx 默认主页index.php vim .../etc/nginx/conf.d/default.conf location / { root /usr/share/nginx/htm ...
- shell升级完整记录
[root@localhost bash-4.3.30]# cat Makefile |grep prefix prefix = /usr/local exec_prefix = ${prefix} ...
- Android仿苹果版QQ下拉刷新实现(二) ——贝塞尔曲线开发"鼻涕"下拉粘连效果
前言 接着上一期Android仿苹果版QQ下拉刷新实现(一) ——打造简单平滑的通用下拉刷新控件 的博客开始,同样,在开始前我们先来看一下目标效果: 下面上一下本章需要实现的效果图: 大家看到这个效果 ...
- 11 个最佳 jQuery 模拟滚动条插件 scrollbar
1. Windows:全屏窗口滚动插件 该插件可以很好地实现全屏滚动,每滚动一次即为一屏.比如,用户浏览下一屏幕内容时,只需手动滚动到某一位置,该插件会自动滚动显示下一屏全部内容.对于浏览类似于PP ...
- weblogic在64位windows的设置
最近遇到一些问题,需要调整weblogic的内存用于做压力测试,weblogic默认的内存是远远不能满足当前测试需求.由于服务器是64位8G的内存,但是在服务器上安装的jdk和weblogic都是32 ...
- linux shell 脚本攻略学习12--文件权限详解,chmod命令详解,chown命令详解,chattr命令详解
文件权限详解 一.chmod命令详解 文件权限和所有权是Unix/Linux文件系统最显著的特征之一.linux中的每一个文件都与多种权限类型相关联,在这些权限中主要分类为3种: 用户(User)是文 ...
- 【Android Studio】为Android Studio设置HTTP代理
[Android Studio]为Android Studio设置HTTP代理 大陆的墙很厚很高,初次安装Android Studio下载SDK等必定失败,设置代理方法如下: 1. 到androi ...
- 004.SMB之guest级别配置
一 配置文件修改 注意: 1 share级别权限访问即,无任何验证共享,对guest开放. 2 新版samba4已取消share级别,可使用user级别配置成无验证共享. 1.1 全局配置文件修改 [ ...
- Generator函数执行器-co函数库源码解析
一.co函数是什么 co 函数库是著名程序员 TJ Holowaychuk 于2013年6月发布的一个小工具,用于 Generator 函数的自动执行.短小精悍只有短短200余行,就可以免去手动编写G ...
- 【Ray Tracing The Next Week 超详解】 光线追踪2-3
Preface 终于到了激动人心的纹理章节了 然鹅,看了下,并不激动 因为我们之前就接触过 当初有一个 attenuation 吗? 对了,这就是我们的rgb分量过滤器,我们画出的红色.蓝色.绿色等 ...