千锋教育-做有情怀、有良心、有品质的职业教育机构

400-811-9990
手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

上海
  • 北京
  • 郑州
  • 武汉
  • 成都
  • 西安
  • 沈阳
  • 广州
  • 南京
  • 深圳
  • 大连
  • 青岛
  • 杭州
  • 重庆
当前位置:郑州千锋IT培训  >  技术干货  >  block为什么能够捕获外界变量?

block为什么能够捕获外界变量?

来源:千锋教育
发布人:xqq
时间: 2023-10-21 05:52:33

一、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
声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。

猜你喜欢LIKE

忘记linux命令怎么办?

2023-10-21

史上最牛linux命令?

2023-10-21

NoteExpress数据库怎么重命名?

2023-10-21

最新文章NEW

linux命令内容导出?

2023-10-21

关于linux命令语句?

2023-10-21

linux配置全局命令?

2023-10-21

相关推荐HOT

更多>>

快速通道 更多>>

最新开班信息 更多>>

网友热搜 更多>>