block传值

2016-02-27  本文已影响381人  和珏猫

一、Block的简单介绍

Block 就是匿名函数 它是封装了一个代码块,这个代码块在什么时候都可以执行;

使用Block的步骤就三步:

1、定义Block变量

2、创建Block的代码块

3、调用Block

(1)无参无返回值

void (^one) = ^{ NSLog(@"hello world!"); };调用 one();

(2)无参有返回值

int (^tow) = ^{ return 1; };调用int a = tow();

(3)有参无返回值

void (^three)(int) = ^(int a){ NSLog(@"hello world!"); };调用int b = 2;three(b);

(4)有参有返回值

int (^four)(int,int) = ^(int a,int b){ return a + b;); };调用 int a = 1; int b = 2;

int sum = four (a , b);

定义Block的另一种方式 一般用 typedef void (^BlockName)( );

二、Block的注意事项

typedef void (^BlockName)( );

1.调用Block的时候首先要判空if (self.BlockName){ 在这里调用Block:self.BlockName( ) };

2.Block可以访问局部变量,但是不能修改它的值如果要修改的话该变量必须用__block修饰

int a = 10; void(^BlockName)() = ^{a++;}; 此处a的值不能修改

原因:此处不能修改的原因是在编译期间确定的,编译器编译的时候把a的值复制到block作为一个新变量(假设是a‘ = 10),此时a'和a是没有关系的

3.如果block块里边有self这样的代码, self必须用__weak 修饰;

__self ViewController *controller = self;

void(^BlockName)() = ^{NSLog(@"%@", controller.string); };

原因:block会对内部的对象进行一次retain,也就是说self会被retain一次。当self释放的时候,需要block释放后才会对self进行释放,但是block的释放又需要等self的dealloc中才会释放。如此一来变形成了循环引用,导致内存泄露。(一句话防止循环引用)

4.在申明block属性的时候用copy 后者strong修饰;

因为默认情况下,block是存档在栈中,可能被随时回收,需要copy到堆区一份,防止被释放掉;

@property(copy,nonatomic)BlockNamemyBlock;

5、在多线程环境下(block中的weakSelf有可能被析构的情况下),需要先将self转为strong指针,避免在运行到某个关键步骤时self对象被析构。

__weak __typeof(self)weakSelf =self;

AFNetworkReachabilityStatusBlock callback= ^(AFNetworkReachabilityStatus status) {

__strong __typeof(weakSelf)strongSelf=weakSelf;

strongSelf.networkReachabilityStatus=status;if(strongSelf.networkReachabilityStatusBlock) {

strongSelf.networkReachabilityStatusBlock(status);

}

};

第四、五、六行,如果不转成strongSelf而使用weakSelf,后面几句话中,有可能在第四句执行之后self的对象可能被析构掉,然后后面的StausBlock没有执行,导致逻辑错误。

这里边的typeof(self) 指的是任意类型

三、Block的使用

Block的使用我就简单说几点应用场景,第一点 他可以传递参数,具体来说就是实现两个ViewController之间值的传递;

第二点 他可以代替代理来使用;

第三点 他可以作为变量来传值,一般在网络请求的时候用的比较多;

.h中声明block,确定block的返回值类型和方法名和传入参数的类型

.m中block方法的实现,这里需要判断block是否为空

在另一个页面.m中调用bolock

上一篇 下一篇

猜你喜欢

热点阅读