热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【ios学习】之七、Blocks简介

blocksblocks是c语言的扩充,他是:带有自动变量(局部变量)的匿名函数。这个概念叫做:闭包。如python中的lambda,在c++11中也引入了lambda;

blocks

blocks是c语言的扩充,他是:带有自动变量(局部变量)的匿名函数。
这个概念叫做:闭包。如python中的lambda,在c++11中也引入了lambda;

维基百科中关于闭包:闭包Closure)是词法闭包Lexical
Closure
)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。

blocks的语法:

^ 返回值类型  参数列表  表达式

^ 参数列表  表达式

^ 表达式



^void (int i){ printf("%d", i);}

^(int i){printf("%d", i);}

^{printf("123");}



这里要注意,当你省略返回值类型的时候,你的表达式里return返回什么类型,那么你的返回值类型就是什么。

当你不适用参数的时候,(void) 参数列表可以省略。



在使用block的时候,我们可以声明block变量,他同c中的函数指针:

int f(int a) {
return a;
}
int (*fa)(int) = &f;


在blocks中,block指源代码中的block语法,也指由block语法生成的值。

int (^blk)(int);
int (^blk)(int) = ^(int a){ printf("%d, a); }
int (^blk1)(int) = blk;
int (^blk2)(int);
blk2 = blk1;




void f(int (^blk)(int));   //向函数传递block

int (^f()(int));    //将block作为返回值返回。



可以使用typedef:

typedef int (^blk_t)(int);
void f(int (^blk)(int)) 对应: void f(blk_t blk)
int (^f()(int)) 对应: blk_t f();




比较函数指针:

int (*ff(int))(int *, int);

这个有点难理解了,我们要从里往外看:

ff(int)   这里将ff声明为一个函数,它有一个int的形参。  

这个函数的返回值就是int (*)(int *, int);

这是一个指向函数的指针。我们来变一下形式:




[cpp] view
plaincopy




  1. typedef int (*func)(int*, int);   

  2. func ff(int)
     





这里可以看到,他们只有一个* 和一个 ^ 的区别。

他可以作为:自动变量,函数参数,静态变量,静态全局变量,全局变量使用。

block类型变量可以和c语言中其他类型变量一样使用。

如: 

typedef int (^blk_t)(int);
blk_t blk = ^(int count){return count;};
blk_t *blkptr = &blk;
(*blkptr)(10);




自动变量

来说一下自动变量:

block表达式截获所使用的自动变量的值:保存该自动变量的瞬间值。

代码解释:

int val = 0;
void (^blk)(void) = ^{printf("%d", val);};
val = 3;
blk();




此时,输出的是0而不是3.



__block



自动变量值截获只能保存执行block语法瞬间的值,保存后不能改写了。 当你在block改写截获的自动变量时,会产生编译错误。

如果想要在block语法的表达式中将值付给block语法外声明的自动变量,那么需要在这个自动变量上附加__weak说明符:

__block int a = 0;

void (^blk)(void) = ^{a = 1;};

blk();



获取的自动变量

id array = [[NSMutableArray alloc]init];
void (^blk)(void) = ^{id obj = [[NSObject alloc]init];
[array addObject:obj];};
id array = [[NSMutableArray alloc]init];
void (^blk)(void) = ^{array = [[NSMutableArray alloc]init];};




上面两段代码第二段会出现错误,应该加上__block说明符。 因为向截获的变量array赋值会产生编译错误。但是使用截获的值是不会产生任何问题的。



const char text[] = "hello";

void (^blk)(void) = ^{printf("%c", text[2]);};



const char *text = "hello";

void (^blk)(void) = ^{printf("%c", text[2]);};

上面两段代码会出现不同的结果,第一段会报错,因为截获自动变量的方法没有实现对c数组的截获。





-----2014/3/18  Beijing

【ios学习】之七、Blocks简介,布布扣,bubuko.com


推荐阅读
  • 本文详细探讨了JavaScript中的作用域链和闭包机制,解释了它们的工作原理及其在实际编程中的应用。通过具体的代码示例,帮助读者更好地理解和掌握这些概念。 ... [详细]
  • 反向投影技术主要用于在大型输入图像中定位特定的小型模板图像。通过直方图对比,它能够识别出最匹配的区域或点,从而确定模板图像在输入图像中的位置。 ... [详细]
  • 本问题探讨了在特定条件下排列儿童队伍的方法数量。题目要求计算满足条件的队伍排列总数,并使用递推算法和大数处理技术来解决这一问题。 ... [详细]
  • JavaScript 基础语法指南
    本文详细介绍了 JavaScript 的基础语法,包括变量、数据类型、运算符、语句和函数等内容,旨在为初学者提供全面的入门指导。 ... [详细]
  • Python 内存管理机制详解
    本文深入探讨了Python的内存管理机制,涵盖了垃圾回收、引用计数和内存池机制。通过具体示例和专业解释,帮助读者理解Python如何高效地管理和释放内存资源。 ... [详细]
  • JSOI2010 蔬菜庆典:树结构中的无限大权值问题
    本文探讨了 JSOI2010 的蔬菜庆典问题,主要关注如何处理非根非叶子节点的无限大权值情况。通过分析根节点及其子树的特性,提出了有效的解决方案,并详细解释了算法的实现过程。 ... [详细]
  • 2018-2019学年第六周《Java数据结构与算法》学习总结
    本文总结了2018-2019学年第六周在《Java数据结构与算法》课程中的学习内容,重点介绍了非线性数据结构——树的相关知识及其应用。 ... [详细]
  • 深入解析Java枚举及其高级特性
    本文详细介绍了Java枚举的概念、语法、使用规则和应用场景,并探讨了其在实际编程中的高级应用。所有相关内容已收录于GitHub仓库[JavaLearningmanual](https://github.com/Ziphtracks/JavaLearningmanual),欢迎Star并持续关注。 ... [详细]
  • 深入解析Java虚拟机(JVM)架构与原理
    本文旨在为读者提供对Java虚拟机(JVM)的全面理解,涵盖其主要组成部分、工作原理及其在不同平台上的实现。通过详细探讨JVM的结构和内部机制,帮助开发者更好地掌握Java编程的核心技术。 ... [详细]
  • 解决Anaconda安装TensorFlow时遇到的TensorBoard版本问题
    本文介绍了在使用Anaconda安装TensorFlow时遇到的“Could not find a version that satisfies the requirement tensorboard”错误,并提供详细的解决方案,包括创建虚拟环境和配置PyCharm项目。 ... [详细]
  • 查找最小值的操作是很简单的,只需要从根节点递归的遍历到左子树节点即可。当遍历到节点的左孩子为NULL时,则这个节点就是树的最小值。上面的树中,从根节点20开始,递归遍历左子 ... [详细]
  • 本文详细解析了Java中hashCode()和equals()方法的实现原理及其在哈希表结构中的应用,探讨了两者之间的关系及其实现时需要注意的问题。 ... [详细]
  • Appium + Java 自动化测试中处理页面空白区域点击问题
    在进行移动应用自动化测试时,有时会遇到某些页面没有返回按钮,只能通过点击空白区域返回的情况。本文将探讨如何在Appium + Java环境中有效解决此类问题,并提供详细的解决方案。 ... [详细]
  • 本题来自WC2014,题目编号为BZOJ3435、洛谷P3920和UOJ55。该问题描述了一棵不断生长的带权树及其节点上小精灵之间的友谊关系,要求实时计算每次新增节点后树上所有可能的朋友对数。 ... [详细]
  • 探讨 HDU 1536 题目,即 S-Nim 游戏的博弈策略。通过 SG 函数分析游戏胜负的关键,并介绍如何编程实现解决方案。 ... [详细]
author-avatar
LD系瑰精棂_142
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有