热门标签 | 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


推荐阅读
  • 深入解析Unity3D游戏开发中的音频播放技术
    在游戏开发中,音频播放是提升玩家沉浸感的关键因素之一。本文将探讨如何在Unity3D中高效地管理和播放不同类型的游戏音频,包括背景音乐和效果音效,并介绍实现这些功能的具体步骤。 ... [详细]
  • 本文探讨了一种常见的C++面试题目——实现自己的String类。通过此过程,不仅能够检验开发者对C++基础知识的掌握程度,还能加深对其高级特性的理解。文章详细介绍了如何实现基本的功能,如构造函数、析构函数、拷贝构造函数及赋值运算符重载等。 ... [详细]
  • 本文介绍了如何通过安装 sqlacodegen 和 pymysql 来根据现有的 MySQL 数据库自动生成 ORM 的模型文件(model.py)。此方法适用于需要快速搭建项目模型层的情况。 ... [详细]
  • 在1995年,Simon Plouffe 发现了一种特殊的求和方法来表示某些常数。两年后,Bailey 和 Borwein 在他们的论文中发表了这一发现,这种方法被命名为 Bailey-Borwein-Plouffe (BBP) 公式。该问题要求计算圆周率 π 的第 n 个十六进制数字。 ... [详细]
  • 我的读书清单(持续更新)201705311.《一千零一夜》2006(四五年级)2.《中华上下五千年》2008(初一)3.《鲁滨孙漂流记》2008(初二)4.《钢铁是怎样炼成的》20 ... [详细]
  • 本文介绍了如何通过C#语言调用动态链接库(DLL)中的函数来实现IC卡的基本操作,包括初始化设备、设置密码模式、获取设备状态等,并详细展示了将TextBox中的数据写入IC卡的具体实现方法。 ... [详细]
  • 本文详细介绍了C++中的构造函数,包括其定义、特点以及如何通过构造函数进行对象的初始化。此外,还探讨了转换构造函数的概念及其在不同情境下的应用,以及如何避免不必要的隐式类型转换。 ... [详细]
  • 本文探讨了使用普通生成函数和指数生成函数解决组合与排列问题的方法,特别是在处理特定路径计数问题时的应用。文章通过详细分析和代码实现,展示了如何高效地计算在给定条件下不相邻相同元素的排列数量。 ... [详细]
  • 探讨如何在映射文件中处理重复的属性字段,以避免数据操作时出现错误。 ... [详细]
  • 利用无代码平台实现高效业务应用开发
    随着市场环境的变化加速,全球企业都在探索更为敏捷的应用开发模式,以便快速响应新兴的商业机遇。然而,传统的软件开发方式不仅成本高昂,而且耗时较长,这往往导致IT与业务部门之间的合作障碍,进而影响项目的成功。本文将探讨如何通过无代码开发平台解决这些问题。 ... [详细]
  • 为何Compose与Swarm之后仍有Kubernetes的诞生?
    探讨在已有Compose和Swarm的情况下,Kubernetes是如何以其独特的设计理念和技术优势脱颖而出,成为容器编排领域的领航者。 ... [详细]
  • 本文探讨了程序员这一职业的本质,认为他们是专注于问题解决的专业人士。文章深入分析了他们的日常工作状态、个人品质以及面对挑战时的态度,强调了编程不仅是一项技术活动,更是个人成长和精神修炼的过程。 ... [详细]
  • 本文介绍了SIP(Session Initiation Protocol,会话发起协议)的基本概念、功能、消息格式及其实现机制。SIP是一种在IP网络上用于建立、管理和终止多媒体通信会话的应用层协议。 ... [详细]
  • 二维码的实现与应用
    本文介绍了二维码的基本概念、分类及其优缺点,并详细描述了如何使用Java编程语言结合第三方库(如ZXing和qrcode.jar)来实现二维码的生成与解析。 ... [详细]
  • 在日常生活中,支付宝已成为不可或缺的支付工具之一。本文将详细介绍如何通过支付宝实现免费提现,帮助用户更好地管理个人财务,避免不必要的手续费支出。 ... [详细]
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社区 版权所有