block使用

Blocks:带有自动变量(局部变量)的匿名函数.

 

之所以能够匿名,是因为C语言函数自己为其创建了名字-->规则是其所在的函数名和该block在其所属函数中所处的顺序值

    //正常的block
    ^int (int count){return count + 1;};
    //block可以省略参数,例如省略返回值类型,则自动使用根据return的类型
    ^(int count){return count + 1;};
    //若不适用参数,则参数列表也可以省略
    ^void(void){};
    //还可以这样写
    ^{};

在OC中,主要使用的是Block类型的变量

Block的可以作为参数传进block里,也可以将Block类型变量作为返回值返回,block之间可以相互赋值,

//点击事件Block
typedef void(^ActionBlock)();
//带参数的Block
typedef void(^CallBackBlock)(id _Nullable obj);
//带参数的Block
typedef void(^StatusBlock)(BOOL status);

// 请求回调block
typedef void(^ Success)(id _Nullable json);
typedef void(^ Failure)(NSString * _Nonnull errorMSG);

直接放在.h里使用方便

Block截获自动变量值

"带有自动变量值"在block里表现为"截获自动变量值"

也就是说:Block表达式截获所使用的自动变量的值,即保存该自动变量的瞬间值.因为Block保存了自动变量的值,所以在执行block语法后,即使改写Block中使用的自动变量的值,也不会影响block执行时自动变量的值.

    //输出应该是2
int
value = 2; void (^block)(void) = ^{ NSLog(@"%i",value); }; value = 10; block();

Block之__block

若想在Block的表达式中将值赋给外部声明的自动变量,需要在该自动变量上附加__block,

    //输出值应该为10
    __block int value = 2;
    void (^block)(void) = ^{
        value = 10;
    };
    block();
    NSLog(@"%i",value);

未添加__block的情况下:截获OC对象,调用变更对象的方法不会有问题,因为block内会截获该对象的结构体实例指针.但是不能对该对象进行赋值操作.

Block的循环引用

原因:在Block中使用强引用的对象,那么Block从栈赋值到堆的时候,该对象为Block持有,就容易引起循环引用

即对象持有block,block又持有对象.死循环

__weak 与 __block的区别

__block在ARC与MRC下都可以使用,可以对对象及基本数据类型进行赋值,修改操作

__weak在ARC下可用,只能修饰对象,不能修饰基本数据类型

__block修饰的对象可以在block中重新赋值,__weak修饰的则不可以

Block修饰符

Block使用copy修饰,因为block默认是在栈区,栈区的特点是随时都可能释放,一旦释放,则调用的就是空指针,copy操作会将其拷贝到堆区,这样的话其生命周期就是随当前对象的生命周期终止才终止,对象不销毁就可以调用

 

posted on 2018-01-18 16:33  咿呀呀呀呀咿  阅读(118)  评论(0编辑  收藏  举报

导航