为什么我选择使用 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 ...
随机推荐
- linux tcp 好文
http://blog.csdn.net/htttw/article/details/7521053
- [topcoder]UnsealTheSafe
http://community.topcoder.com/stat?c=problem_statement&pm=4471&rd=10711 这题果然是道简单题,图+DP.拿道题便觉 ...
- 多线程操作中为什么使用while而不是if来做判断状态是否就绪
在多线程操作中,我们常常会遇到需要先判断信号量状态是否就绪,然后执行后续操作的场景.这里对状态的判断使用的是while而不是单线程下常用的if. 以下示例展示了一个简单的生产者-消费者模型:当队列满的 ...
- 【HDOJ】1422 重温世界杯
简单题. #include <stdio.h> #define MAXN 100005 int wi[MAXN], li[MAXN]; ]; int main() { int n, tot ...
- mysql排序,可以对统计的数据进行排序
sql SELECT a.*,b.name as address_name,b.tel as address_tel,b.province as address_province,b.city as ...
- bzoj1816
这道题不是很难,二分答案+判定即可 注意在一套牌中Joker只能用一次 ..] of longint; mid,l,r,n,m,i,ans:longint; function check(x: ...
- centos6.5 设置静态ip地址
vim /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 #描述网卡对应的设备别名,例如ifcfg-eth0的文件中它为eth0BOOTPRO ...
- eclipse中 com.sun.image.codec.jpeg.JPEGCodec 无法编译通过问题
在Eclipse中处理图片,需要引入两个包:import com.sun.image.codec.jpeg.JPEGCodec;import com.sun.image.codec.jpeg.JPEG ...
- Android 布局之DrawLayout
在刚开始学android的时候肯定会知道,android的主要的布局就是LinearLayout.RelativeLayout.FramLayout.AbsoluteLayout.以及TableLay ...
- POJ1664
Problem B Time Limit : 2000/1000ms (Java/Other) Memory Limit : 20000/10000K (Java/Other) Total Su ...