美文网首页
block 深入浅出

block 深入浅出

作者: Bruce_XHG | 来源:发表于2019-10-07 01:03 被阅读0次
  • 首先block 是一个匿名函数

  • block 有捕获外部变量的能力

  • block 声明的时候是使用 copy 还是 strong

  • block的类型有哪些

  • 如何解决 block 的循环引用问题(只能使用 __weak 吗)

  • 为什么使用__block 可以在 block 内修改外部变量的值

  • 使用 clang 查看 block 内部实现

    1. block 是一个匿名函数,我们就要从其语法定义说起(show the code)

    • c函数(void返回值、funName 函数名、int a 参数、{printf(%d\n,a)函数表达式})
     void funcName(int a)  {
         printf("%d\n", a);
     };
    
    • block(^脱字符、int 返回值、void 参数、{return 3;};表达式)
    ^int (void){
            return 3;
        };
    
    • block使用我们可以看出右边的 block 块是有参数无返回值类型
    typedef void(^cycleBlockTest)(Block1ViewController *);
    @property(nonatomic,copy) cycleBlockTest testBlock;
    self.testBlock = ^ (Block1ViewController *vc){
            [vc doSomeThing];
        };
        self.testBlock(self);
    
  • 由以上对比可以看出c 函数和 block 匿名函数的区别,以及为什么我们把 block 叫匿名函数

2、为什么说 block 有捕获外部变量的能力(show the code

int a = 10;
    void (^block)() = ^{
        DebugLog(@"a = %d",a);
    };
    a++;
    block();
    DebugLog(@"a = %d",a);   
  • 输出结果分别是:10,11。这是为什么呢?这就是 block 的捕获外部变量的能力。那么 block 是如何捕获的呢,请在本文最后查看如何使用 clang 命令查看 block 内部实现,这里会讲述 block 是如何捕获外部变量。

3、block 在其声明的时候当在 MRC 的环境中使用 copy,当在 ARC 的环境中可使用 copy 也可以使用 strong。目前在 ARC 环境中我们一直还在使用 copy 的原因是延续了 MRC 时代的写法。

4、block 类型我们可以从两方面来说:一、内存分布上;二、声明上。

  • 内存分布上

__NSGlobalBlock 全局 block

void(^block)() = ^{
        DebugLog(@"block");
    };
    block();
    DebugLog(@"%@",block);
    
    block
Block1ViewController.m:60   
<__NSGlobalBlock__: 0x10089c110>

__NSStackBlock 栈 block

int a  = 10;
    void(^block)() = ^{
        DebugLog(@"block-%d",a);
    };
    block();
    DebugLog(@"%@",^{
        DebugLog(@"block-%d",a);
    });
    
    Block1ViewController.m:62   
<__NSStackBlock__: 0x16cf8ba20>

__NSMallocBlock 堆 block

int a  = 10;
    void(^block)() = ^{
        DebugLog(@"block-%d",a);
    };
    block();
    DebugLog(@"%@",block);
    
    block-10
Block1ViewController.m:59   
<__NSMallocBlock__: 0x283394ae0>

  • block声明上

无参数无返回值 void(^block)()

有参数无返回值 void(^block)(int a)

无参数有返回值 int(^block)()

有参数有返回值 int(^block)(int a,int b)

5、如何解决 block 的循环问题(有三种方法show the code)

1、 __weak __strong

__weak typeof(self)weakSelf = self;
    self.testBlock = ^{
        __strong typeof(weakSelf)strongSelf = weakSelf;
        [strongSelf doSomeThing];
    };
    self.testBlock();

2、__block

__block Block1ViewController *vc = self;
    self.testBlock = ^{
        [vc doSomeThing];
        vc = nil;
    };
    self.testBlock();

3、self 作为参数

self.testBlock = ^(Block1ViewController *vc){
        [vc doSomeThing];
    };
    self.testBlock(self);

6 __block修改局部变量 clang 查看内部实现 可以查看下图以及本文全部整理都在图中。

image

相关文章

  • 2019-07-20

    Block深入浅出

  • 有关block的学习

    深入浅出Block的方方面面

  • Block深入浅出 (二)

    这篇文章继续上一篇Block深入浅出 (一)讲解block的存储和copy问题 三 Block的存储和copy...

  • Block 深入浅出

    iOS Block用法和实现原理 《Objective-C高级编程》是一本有趣又难懂的书,全书就讲了引用计数、Bl...

  • Block深入浅出

    Block 匿名函数,能够自动捕捉变量

  • 深入浅出 block

    前言 由于笔者前段时间一直忙着上家公司交接和找工作,近期文章很少有更新。简单说一下前几天的面试感触,总共面试了七家...

  • 深入浅出Block

    ps:看网上的东西最好自己试一下,别人讲的东西不一定是正确的。 Block概要 什么是Block Blocks是C...

  • Block深入浅出

    Block的种类 Block分为三类1.NSGlobalBlock: 静态区2.NSMallocBlock: ...

  • Block深入浅出

    一、概述 闭包 = 一个函数『或指向函数的指针』 + 该函数执行的外部的上下文变量 『也就是自由变量』;Block...

  • Block深入浅出

    一:什么事Block Block 是将函数及其执行上下文封装起来的对象。 基本使用: 在方法中生命 typedef...

网友评论

      本文标题:block 深入浅出

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