浅谈 block 的使用

43 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情

什么是block

block是相当于安卓种的内联函数,他的使用非常的灵活,在GCD、URLSession等当中使用非常的方便,我更多的是把它当成是一个简便的从后往前一个方法或者机制。

block 的定义方法

  1. 在 B 的 .h 文件中直接设置 block 属性
@property (nonatomic, copy) void (^block)();
  1. 或者可以先定义一个总的 block 格式:
typedef void (^block)();

在通过这个格式定义对象:

@property (nonatomic, copy) block block;

两者在本质上没有区别,使用时候选择哪一个更合适,多个 block 的时候,我喜欢用方法2,在少量的情况下,我更喜欢使用方法1

block 的使用方法

block 的简单使用

什么情况下用 block 进行简单传值

假设我们有两个界面,一个名为A,一个名为B,这时候我们从A中包含着对象B,在B中完成了一系列动作后,我们想把一些信息或者消息发送给A,通过使用block,可以简单,方便的完成简单传值。

具体使用

在 A 的方法中设置 B 对象的 Block 的动作

-(void)jump {
    B *b = [B new];
    b.block = ^{
        NSLog(@"Get");
    };
    [self presentViewController: animated:YES completion:nil];
}

在 A 中设置回调之后就需要设置动作的触发点了,触发很简单,只要在B的任意位置输入

self.block();

当执行到这一步的时候就会执行一次A页面当中的block操作。

如果想要传值就把 block 的属性增加变量,例如我需要传一个 BOOL 类型的值,则写为:

@property (nonatomic, copy) void (^block)(BOOL Flag);

A中的 block 定义则写为:

b.block = ^(BOOL Flag){
    NSLog(@"%hhd",Flag);
}

在b中的调用为:

self.block(YES);

注意:B中可以多次调用A的 block,只要执行到self.block()就调用。

block 作为方法参数使用

什么情况下作为方法参数使用

在很多情况下,我们需要执行一个方法,而需要返回多个值,或者该方法的主要内容在其他线程中调用,无法返回值,这个时候就可以选择将 block 作为方法参数使用。

具体使用

以我网络请求的一个方法为例:

+ (void)postWithParam:(NSDictionary *)dict successBlock:(void(^)(NSDictionary *dict))successBlock failBolck:(void(^)())failBlock

网络请求有两种情况:成功与失败,不同的情况执行不同的回调

+ (void)postWithParam:(NSDictionary *)dict successBlock:(void(^)(NSDictionary *dict))successBlock failBolck:(void(^)())failBlock{
    [网络请求 请求事件:{
        if (请求成功) {
            if (successBlock) {
                successBlock(请求回调);
            }
        }
        else if (请求失败) {
            if (failBlock) {
                failBlock();
            }
        }
    }];
}

其余的使用详情与简单使用中的类似。

block 作为返回值使用

什么情况下作为返回值使用

有时候,方法需要返回值,但是返回值却在其他线程中获取,则无法通过普通方法直接 return 返回值,此时就应该将 block 作为返回值,该 block 定义为可以返回所需要的返回值类型的 blcok。说着容易乱,看下面例子更好理解。

具体使用

再次以网络回调为例,需要的是知道网络请求是否成功,成功返回 YES,失败返回 NO,只是一个