为什么我选择使用 Blocks(块)
扯淡:到了新公司接手新框架之后,发现大量的使用Blocks,之前很多时候都是使用代理,突然面对这个陌生的语法,特地科普总结了一番。
什么是Blocks
一句话概括就是,带有局部变量的匿名函数(即不带名称的函数)。也称为闭包。
Blocks语法
^ 返回值类型 参数列表 表达式
//例如
^int (int count) { return count + 1; }
上述表达式中,返回值类型 以及 参数列表可以省略(如下), 语法加粗表明不可缺少的部分。
^ {
printf("Hello, blocks");
}
将Blocks声明为属性
多数情况下,我们会把Blocks声明为属性,便于调用。可以利用关键字typedef 对Blocks进行别名。
typedef 返回值类型 (^Blocks别名)(参数列表);
typedef int (^blk_t)(int);
//将Blocks声明为属性
@property (nonatomic, copy) blk_t blk;
//对Blocks进行声明定义
blk = ^(int count) { return count + 1; };
//调用Blocks 和 调用C语言声明函数方式一样
NSLog(@"%d\n", blk(10));
将Blocks作为参数传入方法中
通常都会事先为Blocks取一个别名,一来方便理解,好吧不装逼,就是偷懒。
//定义:
typedef void(^Block)(int a);
- (void)nslogParameterWithBlock:(Block)block {
if (block) {
block(10);
}
}
//赋值并调用
[object nslogParameterWithBlock:^(int a) {
NSLog(@"%d", a);
}];
Blocks截获自动变量值
什么是截获自动变量值,所谓自动变量,就是局部变量。那为什么会截获呢?先来看个例子。
int val = 10;
void (^block)(void) = ^ { printf("val = %d", val); };
val = 20;
block(); //此处调用block,打印为val = 10;
之所以没有打印val = 20,是因为该Blocks在编译期就进行了初始化,对声明的val进行截获,也就是说,把val拷贝一份存入Blocks中。所以当外部val进行了修改时,不影响Blocks截获的val值。
__block 关键字
从上个例子中,我们知道Blocks会对变量进行截获。那如果我非要在Blocks中修改外部参数怎么办呢?我们可以通过__block关键字做到!
__block int val = 10;
void (^block)(void) = ^ { printf("val = %d", val); };
val = 20;
block(); //此处调用block,打印为val = 20;
通过__block说明符对外部参数进行声明后,实际上,相当于在声明定义Blocks的时候,不是通过拷贝内存的方式拷贝外部参数,而是通过指针指向该外部变量,从而达到可以在Blocks中修改的效果。
总结:
Blocks使用方便,但是block的内存管理确实是一项非常重要也非常容易出错的地方,稍不注意便会造成内存泄露,所以,在使用Blocks的时候,也要小心。
因为是匿名函数,所以在项目中多人合作的时候,最后写上每个Blocks的注释说明。
后续将继续总结Blocks的内存管理内容。
为什么我选择使用 Blocks(块)的更多相关文章
- 企业架构研究总结(35)——TOGAF架构内容框架之构建块(Building Blocks)
之前忙于搬家移居,无暇顾及博客,今天终于得闲继续我的“政治课”了,希望之后至少能够补完TOGAF方面的内容.从前面文章可以看出,笔者并无太多能力和机会对TOGAF进行理论和实际的联系,仅可对标准的文本 ...
- TOGAF架构内容框架之构建块(Building Blocks)
TOGAF架构内容框架之构建块(Building Blocks) 之前忙于搬家移居,无暇顾及博客,今天终于得闲继续我的“政治课”了,希望之后至少能够补完TOGAF方面的内容.从前面文章可以看出,笔者并 ...
- 选择屏幕(Selection Screen)
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- UBI(unsorted block image )块管理
一.介绍 ubi是unsorted block images的缩写,是由IBM开发设计的,它与ubifs有不同的含义,ubifs是一种文件系统(nokia开发的):而ubi是一种块管理工具,工作在mt ...
- vim中对文本的选择
本文主要解说vim中对文本的选择,vim中选择文本分为: (1)选择字符 ---- 命令行模式下输入小写v (2)选择行 ---- 命令行模式下输入大写V (3)选择块 ---- ...
- [Q]无矩形外框块参照图形的识别
该图纸的图框由块参照组成,其外侧图框不是矩形 使用默认设置无法正确识别,需要做以下修改:不勾选“块/外部参照”,勾选“块/外部参照边界”,勾选“制定块”并选择图框(块参照).
- Tiled Editor 图块的两种导入方式
一.图块集图块的导入. 打开或者创建地图后,新建 新图块. 弹出新图块面板 图块类型选择 "基于图块集图块",一定要选择"嵌入地图",否则需要另存为其他类型的文 ...
- 5210: 最大连通子块和 动态DP 树链剖分
国际惯例的题面:这题......最大连通子块和显然可以DP,加上修改显然就是动态DP了......考虑正常情况下怎么DP:我们令a[i]表示选择i及i的子树中的一些点,最大连通子块和;b[i]表示在i ...
- 网络应用(4):块的概念 | Range
分块来处理,也算是自然的想法,就是化整为零.而于对于文件的下载同样使用这个道理,既可整体下载,也可分块下载. 小程这里以http协议为例,来看一下块的概念与使用. http的range http1.0 ...
随机推荐
- 字符串还可以这样初始化--uboot篇
- 通过阅读ASP.NET MVC5 框架解密 路由的一点心得
路由: 1.在ASP.NET中路由不专属与ASP.NET MVC,因为路由(Route)是在system.web 命名空间下的,所以传统的WebForm也可以使用路由. 2.什么叫做路由 采用某种机制 ...
- Android 开发遇到的问题及解决办法
Failed to resolve: com.android.support:appcompat-v7:23.4.0 问题解决办法: 1.在Android SDK Manager中找到对应的SDK版本 ...
- 学习Swift -- 协议(下)
协议(下) 在拓展中添加协议成员 通过扩展使得Dice类型遵循了一个新的协议,这和Dice类型在定义的时候声明为遵循TextRepresentable协议的效果相同.在扩展的时候,协议名称写在类型名之 ...
- C++ 利用socket实现TCP,UDP网络通讯
学习孙鑫老师的vc++深入浅出,有一段时间了,第一次接触socket说实话有点儿看不懂,第一次基本上是看他说一句我写一句完成的,第二次在看SOCKET多少有点儿感觉了,接下来我把利用SOCKET完成T ...
- 用C++实现绘制标尺的方法,使用了递归
在这个例子当中将使用递归来实现一个打印标尺刻度的方法.首先是递归,函数调用其本身就叫递归,在需要将一项工作不断分为两项较小的.类似的工作时,递归非常有用,递归的方法被称为分而治之策略. 下面是一个wi ...
- HNOI2015滚粗记
HNOI2015滚粗记 经过两天的苦战,艰难的HNOI终于结束了.感觉这次HNOI自己还是收获了许多. \(Day1\)打的很是艰难,题目一下就有种晕头转向的感觉.开场\(20min\)自己还在读题时 ...
- [BZOJ 3144] [Hnoi2013] 切糕 【最小割】
题目链接:BZOJ - 3144 题目分析 题意:在 P * Q 的方格上填数字,可以填 [1, R] . 在 (x, y) 上填 z 会有 V[x][y][z] 的代价.限制:相邻两个格子填的数字的 ...
- jinfo命令(Java Configuration Info)
jinfo可以输出并修改运行时的java 进程的opts.用处比较简单,用于输出JAVA系统参数及命令行参数.用法是jinfo -opt pid 如:查看2788的MaxPerm大小可以用 jin ...
- R语言 典型相关分析
1.关键点 #典型相关分析##典型相关分析是用于分析两组随机变量之间的相关程度的一种统计方法,它能够有效地揭示两组随机变量之间的相互(线性依赖)关系#例如 研究生入学考试成绩与本科阶段一些主要课程成绩 ...