美文网首页
Block深入浅出

Block深入浅出

作者: Eddiegooo | 来源:发表于2018-12-02 09:25 被阅读13次
    Block的种类

    Block分为三类
    1.NSGlobalBlock: 静态区
    2.NSMallocBlock: 堆 Block
    3.NSStackBlock: 栈Block

        void(^fisrtBlcok)(void) = ^{
            NSLog(@"blcok");
        };
        NSLog(@"第一种%@",fisrtBlcok);
    
        NSInteger a = 10;
        void(^blcok)(void) = ^{
            NSLog(@"Hello block = %ld", a);
        };
        blcok();
        NSLog(@"第二种%@",blcok);
        
        NSLog(@"第三种Block: %@",^{
            NSLog(@"===%ld",a);
        });
    
    
    解决Block循环引用方法
    1. Strong weak dance 这个不多说
        self.name = @"Eddiegooo";
        __weak typeof(self) weakSelf = self;
        self.testBlock = ^{
            __strong typeof(weakSelf) strongSelf = weakSelf;
            NSLog(@"%@", strongSelf.name);
        };
    

    2.mrc: __block

        __block SecViewController *weakVC = self; //这里是重新copy了一份:
        //weakVC  ---> self ---> testBlock ---> weakVC = nil
        self.testBlock = ^{
            NSLog(@"%@",weakVC.name);
            //注意 必须置为nil
            weakVC = nil;
        };
        //这里必须还要掉用一下
        self.testBlock();  //调用Block, weakVC 就置nil了
    
    

    3.把self当参数传递方式
    Block 循环引用: self ---> block ---> self.
    self持有Block, Block持有self。 这时打破这个环即可解决。
    self ----> block ----> vc

    typedef void(^block)(SecViewController *vc);
    
    @interface SecViewController ()
    
    @property (nonatomic, strong) NSString *name;
    @property (nonatomic, copy) block testBlock;
    
    @end
    
        self.testBlock = ^(SecViewController *vc) {
            NSLog(@"%@", vc.name);
        };
        self.testBlock(self); //self当临时变量参数
    
    深究Block原理

    1.创建一个c文件
    终端: vim block.c
    写入C函数:

    #include <stdio.h>
    int main() {
      int a = 10;
    void(^block)(void) = ^{
      printf("%d", a);
    };
    
    block();
    return 0;
    }
    

    2.执行C函数
    gcc block.c 输入一个a.out 的可执行文件。
    ./a.out 执行它。 可以看到打印结果。
    clang -rewrite-objc block.c 执行完得到block.cpp这个文件,打开看下什么东西。

    文件.png
    打开这个block.cpp 文件,一脸懵逼啊
    懵逼文件.png

    别怕慢慢看,其实这就是消息转发。 我们把文件拉倒最下面,就能找到main函数了。


    main 函数.png

    然后在点到文件里面去看下什么意思,值拷贝。

    当我们把block.c 文件里,int a = 10, 前面加上__block ,在clang 一次。发现main函数变化很大哇:


    __block 后的main函数.png

    __block 这个就是浅copy作用。

    Block应用:链式编程 + 函数式编程

    链式编程:

    //想要使用s链式编程,用点语法调用函数,返回IMP的第一个参数self
    - (ViewController *)select {
        NSLog(@"Select");
        return self;
    }
    
    //返回一个Block参数
    - (NSString *(^)(NSString *))where {
        NSString *(^block)(NSString *) = ^(NSString *word) {
            return [NSString stringWithFormat:@"向大家说:%@", word];
        };
        return block;
    }
    

    这样就可以调用点语法函数了。
    NSLog(@"%@",self.select.where(@"niubi"));

    函数式编程:
    y= f(x) ---> y = f(f(x));

    //函数式Demo
    - (void)functionCompletion:(void(^)(NSString *))completion {
        if (completion) {
            //灵活 异步 传值
            completion(@"调用完成了");
        }
    }
    

    使用:

        //把完成的结果传过来使用
        [self functionCompletion:^(NSString *word) {
            NSLog(@"%@",word);
        }];
    

    类似这种应用很多吧,在网络请求用到的最多吧。

    函数式编程方法封装:
    比如UIButton addtarget。 Button和方法实现分开的。 这时候可以用函数式编程,将定义button和方法放在一起,用Block回调。

    相关文章

      网友评论

          本文标题:Block深入浅出

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