block为什么能够捕获外界变量?
一、block能够捕获外界变量的原因
在定义Block的时候,外界变量被编译器转换成了结构体成员变量,并且在调用Block的时候,这些变量的值会被拷贝到Block的结构体实例中。这样一来,即使在Block执行之后,这些变量的作用域已经结束,它们的值也能够保留下来,并且能够在Block内部继续使用。这种特性就是Block所具有的闭包特性,也是它能够捕获外界变量的原因。
二、block是什么
block是一种封装了代码块的数据类型,可以在C、Objective-C和Swift中使用。它类似于函数或方法,但具有更灵活的特性,可以嵌套在其他代码块中使用,并且能够捕获外部变量。block可以作为参数传递给函数或方法,也可以作为返回值返回。在异步编程、多线程和事件处理等场景中,block被广泛应用。
block就是一个代码块, block是将函数及其执行上下文封装起来的对象,是一个匿名的函数对象, block也有isa。既然block内部封装了函数,那么它同样也有参数和返回值,本身也可以被作为参数在方法和函数间传递。
block标准语法:
return_type (^blockName)(var_type) = ^return_type (var_type varName) { // ...};blockName(var);
三、Block底层实现
block的底层实现是结构体,和类的底层实现类似,都有isa指针,可以把block当成是一个对象。下面通过创建一个控制台程序,来窥探block的底层实现。
block 的内存结构图:
Block_layout结构体成员含义如下:
isa: 指向所属类的指针,也就是block的类型flags: 标志变量,在实现block的内部操作时会用到Reserved: 保留变量invoke: block执行时调用的函数指针,block内部的执行代码都在这个函数中descriptor: block的详细描述,包含 copy/dispose 函数,处理block引用外部变量时使用variables: block范围外的变量,如果block没有调用任何外部变量,该变量就不存在Block_descriptor结构体成员含义如下:
reserved: 保留变量size: block的内存大小copy: 拷贝block中被 __block 修饰的外部变量dispose: 和 copy 方法配置应用,用来释放资源具体实现代码:
enum { BLOCK_REFCOUNT_MASK = (0xffff), BLOCK_NEEDS_FREE = (1 << 24), BLOCK_HAS_COPY_DISPOSE = (1 << 25), BLOCK_HAS_CTOR = (1 << 26), /* Helpers have C++ code. */ BLOCK_IS_GC = (1 << 27), BLOCK_IS_GLOBAL = (1 << 28), BLOCK_HAS_DESCRIPTOR = (1 << 29)};/* Revised new layout. */struct Block_descriptor { unsigned long int reserved; unsigned long int size; void (*copy)(void *dst, void *src); void (*dispose)(void *);};struct Block_layout { void *isa; int flags; int reserved; void (*invoke)(void *, ...); struct Block_descriptor *descriptor; /* Imported variables. */};
延伸阅读1:block类型
NSGlobalBlock:没有访问auto变量NSStackBlock:访问了auto变量NSMallocBlock:调用了copy相关推荐HOT
更多>>怎么做一个简单的数据库,可以实现模糊查找检索?
一、做一个简单的实现模糊查找检索的数据库的方法1、创建数据库表格首先需要创建一个数据表格用来存储数据,表格结构应该与你要存储的数据类型...详情>>
2023-10-14 18:58:50oracle为什么要继续开发mysql?
一、oracle为什么要继续开发mysql应该是之前收购的时候有协议吧,而且,本身面向的客户也不太一样。oracle也有不付费的用户,mysql有社区版,但...详情>>
2023-10-14 18:32:39block为什么能够捕获外界变量?
一、block能够捕获外界变量的原因在定义Block的时候,外界变量被编译器转换成了结构体成员变量,并且在调用Block的时候,这些变量的值会被拷贝...详情>>
2023-10-14 11:33:56MySQL数据库备份方法有什么?
一、MySQL数据库备份方法1、使用mysqldump命令mysqldump是MySQL提供的官方备份工具,可以将数据库以SQL格式导出到文件中。可以使用以下命令进行...详情>>
2023-10-14 09:55:06热门推荐
数据的批处理和流处理有什么区别?
沸在信息检索中检索式与提问式有什么区别?
热无连接机制的木马程序和传统的木马程序有什么区别?
热ejb和spring的区别?
新jndi和jdbc区别?
ground和floor的区别?
Local 变量和 Field 变量有哪些区别?
循环程序结构和分支程序结构有哪些区别?
怎么做一个简单的数据库,可以实现模糊查找检索?
oracle为什么要继续开发mysql?
Java怎么注解实体类实现数据库类型与Java类型对应映射?
Filemaker集合前端后台,可为什么Apple最后用的解决方案是SAP?
用char储存时间与用datetime有什么区别?
在分布式数据库存储中,数据分区和数据放置有什么区别?