美文网首页
到底什么是block?

到底什么是block?

作者: 水蜜桃看看就好 | 来源:发表于2021-04-21 11:05 被阅读0次

简述Block

block 是 C 语言的扩充功能,我们可以认为它是 带有自动变量的匿名函数,同时也是一个对象。

  • 首先Block声明及定义语法,及其变形
1 标准定义
returnType(^blockName)(var_type) = ^returnType(var_type varName){ //操作 }
举个🌰 :
void(^defalutBlock)(NSString *) = ^void(NSString *name){ NSlog(@"%@",name)}

2 省略缩写
returnType(^blockName)(var_type) = ^(var_type varName){ //操作 }
举个🌰 :
void(^defalutBlock)(NSString *) = ^(NSString *name){ NSlog(@"%@",name)}

3 typedef简化Block的声明
typedef return_type (^BlockTypeName)(var_type);
  • 接下来我们看几个面试题来分析下

1.block的原理是怎样的?本质是什么?
2.__block的作用是什么?有什么使用注意点?
3.block的属性修饰词为什么是copy?使用block有哪些使用注意?
4.block在修改NSMutableArray,需不需要添加__block

问题1: block原理是什么?本质是什么?

写个block

int main(int argc, char * argv[]) {
    int(^block)(int)=^int(int a)
    {
        return  a;
    };
    block(8);
    
    return  0;
}

通过使用clang命令,将.m文件转换成.cpp文件clang -rewrite-objc main.m

int main(int argc, char * argv[]) {

    int(*block)(int)=((int (*)(int))&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));
    ((int (*)(__block_impl *, int))((__block_impl *)block)->FuncPtr)((__block_impl *)block, 8);

    return 0;
}

C++定义block变量代码 其中不难看出 将__main_block_impl_0函数的地址赋值给了block

 int(*block)(int)=((int (*)(int))&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));

我们接着看下__main_block_impl_0是什么?是一个结构体

struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

注意:__main_block_impl_0结构体中 有同名的构造函数__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) 其中的fp 可以理解为方法的地址

我们可以看到__main_block_desc_0中存储着两个参数,reserved和Block_size,并且reserved赋值为0而Block_size则存储着__main_block_impl_0的占用空间大小。最终将__main_block_desc_0结构体的地址传入__main_block_func_0中赋值给Desc

static struct __main_block_desc_0 {
  size_t reserved;
  size_t Block_size;
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};

我们再来看下__block_impl结构体

struct __block_impl {
  void *isa;
  int Flags;
  int Reserved;
  void *FuncPtr;
};

我们可以发现__block_impl结构体内部就有一个isa指针。因此可以证明block本质上就是一个oc对象。而在构造函数中将函数中传入的值分别存储在__main_block_impl_0结构体实例中,最终将结构体的地址赋值给block。

分析得出

  1. __block_impl结构体中isa指针存储着&_NSConcreteStackBlock地址,可以暂时理解为其类对象地址,block就是_NSConcreteStackBlock类型的
  2. block代码块中的代码被封装成__main_block_func_0函数,FuncPtr则存储着__main_block_func_0函数的地址。
  3. Desc指向__main_block_desc_0结构体对象,其中存储__main_block_impl_0结构体所占用的内存。

问题总结:


此时已经基本对block的底层结构有了基本的认识,上述代码可以通过一张图展示其中各个结构体之间的关系。

image
本文有参考其他作者:
block文章---xxcc

相关文章

  • 到底什么是block?

    简述Block block 是 C 语言的扩充功能,我们可以认为它是 带有自动变量的匿名函数,同时也是一个对象。 ...

  • Block的深入与浅出

    谈到block,我们通常称之为代码块,那么block的本质到底是什么呢? block的实质上是对象, 一个函数指针...

  • 2022-04-13 block笔记

    什么是block 什么是block调用 block截获变量 __block修饰符用在什么场景,__block变量_...

  • Block(二)

    Block 到底是什么? 它就是里面存储了指向定义Block时的代码块的函数指针,以及Block 外部上下文变量信...

  • 2019 iOS面试题-----Block原理、Block变量截

    什么是Block? Block变量截获 Block的几种形式 一、什么是Block? Block是将函数及其执行上...

  • iOS block

    block的数据结构 先来一个最简单的block,看看这个block到底执行了什么 cd 到main.m的目录下,...

  • 把OC代码 编译成C/C++

    有时候 看到oc的代码,但是不知道里面做了什么 ,就例如OC里面的block ,他到底做了什么呢,__block...

  • 面试小结

    1. 在使用block中,局部变量为什么要用__block修饰才能改变它的值?,到底发生了什么? 可以做一个测试...

  • block 记录

    2015年12月11日星期五 block 的性质 block与delegate的区别说到底,block是函数(转码...

  • Block本质

    底层实现 项目开发中我们经常使用block,今天我们就一起研究一下block,我们一起看一下block到底是什么。...

网友评论

      本文标题:到底什么是block?

      本文链接:https://www.haomeiwen.com/subject/ocjalltx.html