又见block(二):block语法定义

本文详细介绍了Block的多种语法定义及其应用场景,包括局部声明、作为属性和方法参数的使用等常见用法,以及内联使用、递归使用和作为返回值等不常见用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在上一篇提到block是带有自动变量(局部变量)的匿名函数,本文来看看block的语法定义

首先作如下约定:

returnType:返回值类型
blockName:block的名称
paraType:参数类型
paraName:参数名称

block的语法定义主要有以下几种:

1、标准的声明与定义

    returnType (^blockName)(paraType) = ^returnType (paraType paraName){
        /*block 内部代码*/

    };
    block(para);

2、返回值类型为void

    void (^blockName)(paraType) = ^void (paraType paraName) {
        /*block 内部代码*/

    };
    block(para);

可以简写如下:

    void (^blockName)(paraType) = ^(paraType paraName) {
        /*block 内部代码*/

    };
    block(para);

3、参数类型为void

    returnType (^blockName)(void) = ^returnType (void) {
        /*block 内部代码*/

    };
    block(para);

可以简写如下:

    returnType (^blockName)(void) = ^returnType {
        /*block 内部代码*/

    };
    block(para);

4、返回值和参数类型都为void

    void (^blockName)(void) = ^void (void) {
        /*block 内部代码*/

    };
    block(para);

可以简写如下:

    void (^blockName)(void) = ^ {
        /*block 内部代码*/

    };
    block(para);

5、block名称为空时
此时blockName为空,即匿名block

block的简化声明

1、利用typedef简化block的声明
typedef returnType (^blockName) (paraType)
例如通过typedef声明一个block后,直接在属性或者方法参数中使用该block

    /*简化block的声明*/
    typedef void (^clickBlock)(NSInteger index);
    @interface ViewController ()
    /*定义一个block的属性*/
    @property (nonatomic,copy) clickBlock buttonClickBlock;
    /*将block作为方法参数*/
    - (void)viewDidSelected:(clickBlock) selected;
    @end

block的用法

  • 常见用法

1、局部声明一个block类型的变量
例如在一个方法的内部定义如下block并且调用这个block

    void (^localBlock)(int number) = ^(int number){
             NSLog("%d \n",number);
        };
    localBlockIn(23);

block返回值为void时进行省略
2、声明一个block类型的属性

    @property (nonatomic,copy) clickBlock buttonClickBlock;

3、block作为方法定义的形参

- (void)viewDidSelected:(clickBlock) selected;

4、方法调用时,block作为实参

- (void)viewDidSelected:(clickBlock)selected {
            self.buttonClickBlock = selected;
        }
  • 不常见用法

1、block作为内联使用,即匿名block被声明后立即调用

^returnType (paraType paraName) {
    /*block 内部代码*/
}(para);

2、block递归使用
block内部调用自身,形成递归递归是很多算法的基础;特别注意的是:由于block内部调用了自身,这里必须用__block避免循环调用

__block returnType (^blockName)(paraType) = [^returnType (paraType paraName) {
    /*递归条件判断*/
    if (returnCondition) {
        blockName = nil;
        return;
    }
    /*block 内部代码*/
    /*递归调用*/
    blockName(paraName);
} copy];
/*首次调用*/
blockName(varValue);

3、block作为返回值
方法的返回值是一个block,常用于一些“工厂模式”的方法中,形式如下:

- (returnType(^)(paraType))methodName {
    return ^returnType(paraType paramName) {
        // ...
    };
}

常用的Masonry框架里面

- (MASConstraint * (^)(id))equalTo {
    return ^id(id attribute) {
        return self.equalToWithRelation(attribute, NSLayoutRelationEqual);
    };
}

链式编程:将block作为方法的返回值,并且返回值的类型为调用者本身,并将该方法以setter形式返回,实现连续调用,即为链式编程

设计一个链式语法的简易加法器,主要代码如下:

@interface CaculateObject : NSObject

/*属性变量*/
@property (nonatomic,assign) NSInteger result;
/*实例方法,返回是一个block,返回类型是调用者本身*/
- (CaculateObject *(^)(NSInteger number))add;

@end

/*方法的实现*/
@implementation CaculateObject

- (CaculateObject *(^)(NSInteger number))add {
    __weak CaculateObject *weakSelf = self;
    /* 返回一个block */
    return ^CaculateObject* (NSInteger number){
        weakSelf.result += number;
        /* 这个block的返回值类型是调用者本身 */
        return self;
    };
}

@end

实际调用为:

    CaculateObject *caculate = [[CaculateObject alloc] init];
    caculate.add(33).add(23);
    NSInteger sum = caculate.result;
    /*结果 sum = 56 */

本篇主要说明了block的定义与用法,后面继续讨论block捕获自动变量(局部变量)的能力,未完待续……

参考链接
又见block(一):block是什么?
又见block(三):block实质
又见block(四):block捕获自动变量
又见block(五): __block变量和对象
又见block(六):block存储域与__block变量存储域
又见block(七):截获对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值