美文网首页
block的基本理解

block的基本理解

作者: 门前的那颗樱桃树 | 来源:发表于2021-05-31 18:16 被阅读0次

什么是Block

1、 Block是将函数及其执行上下文封装起来的对象

{ 
      int multiplier = 6;
      int(^Block)(int) = ^int(int num) {
            return num*multiplier;
      };
      Block(2);
}
BLOCK.png

2、 截获变量

  • 局部变量: 基本数据类型对象类型

  • 静态局部变量

  • 全局变量

  • 静态全局变量

  • 对于基本数据类型的局部变量截获其值。

  • 对于对象类型的局部变量连同所有权修饰符-起截获。

  • 指针形式截获局部静态变量

  • 不截获全局变量、静态全局变量

{ 
      int multiplier = 6;
      int(^Block)(int) = ^int(int num) {
            return num*multiplier;
      };
      multiplier = 4;
      NSLog(@"结果=%d", Block(2));
}
那么这里的 结果就是12
{ 
      static int multiplier = 6;
      int(^Block)(int) = ^int(int num) {
            return num*multiplier;
      };
      multiplier = 4;
      NSLog(@"结果=%d", Block(2));
}
那么这里的 结果就是8

3、一般情况下,对被截获变量进行赋值操作需要添加__block修饰符
赋值 != 使用

这里就是使用
{
      NSMutableArray  *array = [NSMutableArray array];
      void(^Block)(void) = ^{
            [array addObject:@"123"];
      };
      Block();
}
这里就需要加__blcok, 这里就是赋值
{
      __block NSMutableArray  *array = nil;
      void(^Block)(void) = ^{
            array = [NSMutableArray array];
      };
      Block();
}

4、对变量进行赋值时
需要__block修饰符: 局部变量(基本数据类型、对象类型)。
不需要__block修饰符: 静态局部变量、全局变量、静态全局变量。

{ 
      __block int multiplier = 6;
      int(^Block)(int) = ^int(int num) {
            return num*multiplier;
      };
      multiplier = 4;
      NSLog(@"结果=%d", Block(2));
}
那么这里的 结果就是8

__block修饰的变量变成了对象

__block int multiplier
struct _Block_byref_mutiplier_0 {
      void * _isa;
      __Block_byref_multiplier_0 * __forwarding;
      int __flags;
      int __size;
      int multiplier;
}
被修饰之后
multiplier = 4
相当于multiplier对象的__forwarding指针。指向multiplier。指向了自己。
(multiplier.__forwarding->multiplier) = 4

5、Block的内存管理
impl.isa = &_NSConcreteStackBlock;

  • _NSConcreteGlobalBlock 全局类型Block
  • _NSConcreteStackBlock 栈类型Block
  • _NSConcreteMallocBlock 堆类型Block

Block的copy操作

Block类别 copy结果
�_NSConcreteGlobalBlock� 数据区� 什么也不做�
�_NSConcreteStackBlock � 堆�
�_NSConcreteMallocBlock� 增加引用计数�
栈上的Block进行copy之后变成堆

栈上的__forwarding指向堆的Block。
堆上的__forwarding指向堆自己的Block。

6、__forwarding总结

{
      __blcok int  multiplier = 10;
      _blk = ^int(int num){
            return num * multiplier;
      };
      multiplier = 6;
      [self executeBlock];
}

- (void)executeBlock {
      int result = _blk(4);
      NSLog(@"result is %d", result);
}
result is 24

不论在任何内存位置, 都可以顺利的访问同一个__block变量。

7、循环引用

{
      _array = [NSMutableArray arrayWithObject:@"123"];
      _strBlock = ^NSString * (NSString * num ) {
            return [NSString stringWithFormat:@"", _array];
      };
      _strBlock(@"123");
}
修改
{
      _array = [NSMutableArray arrayWithObject:@"123"];
      __weak NSArray * weakArray = _array;
      _strBlock = ^NSString * (NSString * num ) {
            return [NSString stringWithFormat:@"", weakArray];
      };
      _strBlock(@"123")l;
}
{
      __block MCBlock * blockSelf = self;
      _blok = ^int(int num){
          // var = 2
          int result = num * blockSelf.var;
          blockSelf  = nil;
          return result;
      };
      _blk(3);
}
image.png
什么是Block?
答: Block是将函数及其上下文进行封装的对象。

为什么Block会产生循环引用?
答:如果当前Block对当前对象的成员变量进行截获,那么这个Block就对这个对象有浅引用。
   这个对象也对Block有浅引用。就产生了自循环引用。

怎么理解Block截取变量的特性?
答:对于`基本数据类型`的`局部变量`,对`值`进行截获。
   对于`对象类型`的`局部变量`连同所`有权修饰符`-起截获。也可以说强引用
   对于静态的变量,对指针进行截获
   对全局变量或者全局静态变量,都不截获

你遇到过哪些循环引用?你是怎么解决的?
答:Block截获的对象,也是当前对象的成员变量。自循环循环变量
      
      用__block来解决,如果是自循环,那就可以是用断环的形式来避免。

相关文章

  • block的基本理解

    什么是Block 1、 Block是将函数及其执行上下文封装起来的对象。 2、 截获变量 局部变量: 基本数据类型...

  • Block 心得体会

    首先不介绍block的基本概念等,推荐对block的精华阐释:block一点也不神秘 其次说说我的理解: 1. 属...

  • Block原理探究(上篇)-Block本质及存储域问题

    主要内容:1.理解Block的本质2.理解Block的存储域分类3.理解Block的Copy原理 一、探究Bloc...

  • block使用及其底层原理

    一 block基本使用 二 block底层结构 三 block变量捕获 四 block的类型 五 block对象类...

  • iOS Swift 模型数组排序(仿写 sortedArrayU

    目的:为了加深对 block 的理解 个人理解:block 的返回值 NSComparisonResult 略带有...

  • iOS-简单两步搞定自定义View

    目录 Block简介/定义Block基本使用Block在C/C++(底层)的数据结构Block的类型 Block简...

  • block用法大全

    block语句块 如何解决block循环引用 高逼格理解block循环引用 block相关

  • block 的理解

    block语法 ^ 返回值类型 ( 参数列表 ) {表达式}; 返回值类型可省略: block的声明:返回值类型...

  • block的理解

    block的理解参照文章http://www.cnblogs.com/flyFreeZn/p/4264220.ht...

  • block的理解

    1..block的原理是什么?本质是什么? block本质上也是一个OC对象,它内部也有个isa指针,block是...

网友评论

      本文标题:block的基本理解

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