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回調。

相關文章
相關標籤/搜索