Block深刻浅出

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: __blockvim

__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 ----> vcbash

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应用:链式编程 + 函数式编程

链式编程:ui

//想要使用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"));atom

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

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

使用:

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

相似这种应用不少吧,在网络请求用到的最多吧。

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

相关文章
相关标签/搜索