Blocks Programming Helper → Blocks can ?

Blocks 可以捕获作用域中的值

- (void)aMethod {
    int anInteger = 1;
    void (^aBlock)(void) = ^{
        //anInteger = 11; //Buildtime error
        NSLog(@"anInteger = %i", anInteger);
    };
    anInteger = 2;
    aBlock(); //anInteger = 1
}

变量“anInteger”定义在“aBlock”的外部,但属于相同的作用域,当定义“aBlock”时,捕获了“anInteger”的值。在“aBlock”定义后,即使修改“anInteger”的值,被捕获的值也不会改变。而且在“aBlock”内部也不能修改“anInteger”的值,可以理解为一个 int const 变量。

若一定要修改变量“anInteger”的值,可以使用 __block 存储类型修饰符定义该变量。

__block int anInteger = 1;
void (^aBlock)(void) = ^{
    anInteger = 11;
    NSLog(@"anInteger = %i", anInteger);
};
anInteger = 2;
aBlock(); //anInteger = 11

使用 __block 修饰变量后,在定义“aBlock”时捕获的不是变量“anInteger”的值而是地址,可以理解为一个 int * const 变量,存储了“anInteger”变量的内存地址,通过地址修改值。

Blocks 可以作为函数和方法的参数

//declare
- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block;

//invoke
[ary enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    //define block
}];

//define (infer)
- (void)enumerateObjectsUsingBlock:(void (^)(id, NSUInteger, BOOL *))block {
    NSUInteger idx = 0;
    BOOL stop = NO;
    for(id obj in self) {
        if (stop) {
            break;
        }
        idx = [self indexOfObject:obj];
        //invoke block
        block(obj, idx, &stop);
    }
}

在封装方法的过程中,需要与外部交互,暴露出方法内部的数据给外部进行相应的处理。通过使用 block 实现了封装固定代码,变化的代码由外部提供,减少冗余代码。

Blocks 可以作为函数和方法的返回值

#import <Foundation/Foundation.h>
//加法类
@interface YGAddition: NSObject
//存储计算结果
@property (assign, nonatomic) NSInteger result;
//加上一个值
- (YGAddition *)add:(NSInteger)value;
//功能同上
- (YGAddition *(^)(NSInteger))add;
@end
#import "YGAddition.h"
@implementation YGAddition
- (YGAddition *)add:(NSInteger)value {
    self.result += value;
    return self;
}
- (YGAddition *(^)(NSInteger))add {
    YGAddition *(^rtn)(NSInteger) = ^(NSInteger value) {
        self.result += value;
        return self;
    };
    return rtn;
}
@end
//demo
YGAddition *adt = [[YGAddition alloc] init];
adt.result = 1;
//invoke "- (YGAddition *)add:(NSInteger)value"
[[adt add:1] add:-1];
//invoke "- (YGAddition *(^)(NSInteger))add"
adt.add(1).add(-1);
NSLog(@"result = %li", adt.result); //result = 1
    原文作者:earlyMorning
    原文地址: https://segmentfault.com/a/1190000012849272
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞