资讯专栏INFORMATION COLUMN

Blocks Programming Helper → Blocks can ?

summerpxy / 796人阅读

摘要:在定义后,即使修改的值,被捕获的值也不会改变。若一定要修改变量的值,可以使用存储类型修饰符定义该变量。通过使用实现了封装固定代码,变化的代码由外部提供,减少冗余代码。可以作为函数和方法的返回值加法类存储计算结果加上一个值功能同上

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 
//加法类
@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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/16934.html

相关文章

  • Blocks Programming HelperBlocks are ?

    摘要:创建一个这个没有参数和返回值。调用一个带参数和返回值的可以带参数和返回值,就像函数和方法一样。返回值被推断从内部,也可以明确指定。使用类型定义如果需要定义多个相同类型的变量,建议使用。不使用类型定义使用类型定义在嵌套时使用,可读性更高。 创建一个 Block void (^aBlock)(void) = ^{ NSLog(@This is a block); }; 这个 blo...

    zhkai 评论0 收藏0
  • Blocks Programming HelperBlocks in System APIs

    摘要:在系统框架中使用的案例包括完成处理器通知处理器视图动画枚举器比较器并行任务完成处理器被调用当动画完成时,有一个参数没有返回值。比较器被调用当比较元素时,有二个参数一个返回值。 系统框架中越来越多的方法和函数,使用 Block 作为参数。Block 在系统框架中使用的案例包括: 完成处理器 通知处理器 视图动画 枚举器 比较器 并行任务 完成处理器 //declare + (void...

    ashe 评论0 收藏0
  • Handlebars partials 隐藏的力量

    摘要:和再来分别看看每个文件文件首先是有些值得注意的地方,拆开来单独看引入了一个虚构的。部分我们又用了,不同的是我们用了基本来指定默认内容。文件拼图的下一部分就是。我们也用到了,同时还有,下面是的示例同样拆开来看看这里又用到了。 一个项目的机会再加上我自己的探索,让我对Handlebars partials有了更深的理解。事实证明,你可以做得比我了解的更多。 我最近在负责一个小项目,只有很少...

    sixleaves 评论0 收藏0
  • 晒一手hbs helper

    摘要:最近项目中用到模版,结合,感觉还不错。其中,是的核心,为了让自己用得更爽,经过搜集和琢磨,留下一手,亲测有效。 最近项目中用到hbs模版,结合express,感觉还不错。其中,helper是handlebar的核心,为了让自己用得更爽,经过搜集和琢磨,留下一手helper,亲测有效。 1. block与extend 源码 let blocks = {}; hbs.registerHel...

    linkFly 评论0 收藏0
  • handlebars.js模板引擎

    摘要:基于,可以在中导入模板。利用对象函数替换对象或者运行函数支持点语法可以对象等属性值使用时,直接标签引入文件。模块会自动匹配相应的数值,对象或者是函数。也可以单独建立一个模板,或者可以用来唯一确定一个模板,是固定写法,不可或缺。 前言:常用的末班引擎有很多,但写法都大同小异。handlebars.js就是一个纯JS库,因此你可以向其他脚本一样用script包起来。调用内部封装好的功能。 ...

    SimpleTriangle 评论0 收藏0

发表评论

0条评论

summerpxy

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<