Block 使用 理解

2019-11-20  本文已影响0人  红色海_

一,基础认识


block的声明

很像函数指针,把 * 换成^ 。前面是返回类型,中间是块名,最后是参数类型。

// returnType (^BlockName) (Parameters)
int (^YourBlockName) (int, int);

// 简化声明,  typedef登场
typedef int(^FuncAdd)(int, int);
FuncAdd add = ^int(int a, int b) {
        return a+b;
};
add(100, 200);
block的实现
// ^returnType(Parameters){/*Put your code abcdefg */};
^int(int a, int b) {
    return a+b;
};

返回值类型是可省略, 可自动判断,如果参数也是空,可简化成这样式儿的:

^( ) {
    ;
};

你可能会觉得,“这是啥啊!”。。

block的使用

根调用C函数一个样

YourBlockName(100, 200)
block特性

捕获 声明所在范围的所有变量。

 int count = 0;
 count = 1;
 int (^block2)(void) = ^{
        return count;
 };
 count = 2;
 int value = block2();   // value = 1

却不能在block中修改捕获到的这些变量,尝试修改编译器报错。
[图片上传失败...(image-b9b6c3-1574265520804)]
)

__block 修饰de变量可在块中修改 值

 __block int count = 0;
 int (^MyBlock)(void) = ^{
    count = 5;
    return count ;
 };
    
 int value1 = count;     // 0
 int value2 = MyBlock(); // 5
 int value3 = count;     // 5

捕获变量只是拷贝了一份变量的值,用 __block 修饰后拷贝的是变量的地址.

循环引用de问题
例如ClassA持有block,block 中又用到了self. 循环引用 内存泄漏了。。。

 __weak typeof(self) weakSelf = self;
YourBlock = ^{
   __strong typeof(self) strongSelf = weakSelf;
   NSLog(@"%@",   strongSelf.********);
};

二,深入理解

block 的本质是啥呢?

/* Revised new layout. */
struct Block_descriptor {
    unsigned long int reserved;
    unsigned long int size;
    void (*copy)(void *dst, void *src);
    void (*dispose)(void *);
};

struct Block_layout {
    void *isa;  // 是个对象
    int flags;
    int reserved; 
    void (*invoke)(void *, ...); // 函数指针
    struct Block_descriptor *descriptor;
    /* Imported variables. */
};
类型

OC 中共有3种:
全局块,不访问任何外部变量
栈块,保存在栈中, 函数退出就被销毁,通过copy可复制到堆上。
堆块,保存在堆中。

MRC 的环境下运行下面的代码:

void (^globalBlock)()  = ^{ NSLog(@"I am global block"); };
NSLog(@"%@", globalBlock);
        
NSString *string1 = @"I am stack block";
void (^stackBlcok)() = ^{ NSLog(@"%@", string1); };
NSLog(@"%@", stackBlcok);
    
NSString *string2 = @"I am malloc block";
void (^mallockBlock)() = [^{ NSLog(@"%@", string2); } copy];
NSLog(@"%@", mallockBlock);

<__NSGlobalBlock__: 0x1000053b0>
<__NSStackBlock__: 0x8fff5fbcc540>
<__NSMallocBlock__: 0x201503da0>
上一篇下一篇

猜你喜欢

热点阅读