iOS开发之 Blocks(闭包)

Blocks是一种应用于 C,Objective-C,C++上的语言层次的功能,一如其他语言如 Swift、Javascript 中的Closures,苹果开发者文档也对其做了初步的介绍Working with Blocks.

Blocks的特点

  • blocks就是一个代码块,但是它在内联(inline)执行的时候(这和C++很像)还可以传递参数。同时blocks本身也可以被作为参数在方法和函数间传递,这就给予了blocks无限的可能
  • 带有自动变量(局部变量)的匿名函数,在某些场合可省去不必要的函数命名再调用流程,以简化常规任务,例如集合枚举,分类和测试

Blocks 语法及使用

Blocks 型变量

返回类型 (^block名)(参数列表)

示例

void (^myBlockName)(int)  

定义 Blocks类型

typedef void(^myBlockName)(int);  

添加 Blocks 类型属性

@property (nonatomic, copy) myBlockName block;

或者定义与添加 Blocks 属性合并

@property (nonatomic, copy) void(^myBlockName)(int);

blocks定义

^ 返回值类型 (参数列表) 表达式

示例

^void (int i){
    NSLog(@"this is a block");
};

其中,返回值类型可以省略,如:

^(int i){
    NSLog(@"this is a block");
};

省略返回值类型时,真实返回值类型将由表达式内return 语句的类型定义,如果表达式内无 return 语句,将自动使用 void 返回类型

当无参数列表时,参数列表块也可以省略,如:

^(void){
    NSLog(@"this is a block");
};

可以省略为:

^{
    NSLog(@"this is a block");
};

Objective-C 函数使用 Block参数

- (void)myFunc:(int (^)(int))para{
    //func expression
}

可通过类似函数指针形式简化函数: 首先定义 block 类型

typedef int(^myBlockName)(int);  

简化函数后

- (void)myFunc:(myBlockName)para{
    //func expression
}

使用 blocks 回调

使用 blocks 回调替代 delegate 或者 notification 在某些场合非常方便,可省去不少的代码量

示例:

如有 TableViewController *VC1,其 cell 为自定义 cell,现欲使 VC1响应 cell 内部按钮的点击事件

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        NSString *cellID = @"blockCell";
        blockCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
        cell.action = ^(blockCell *cell){
            // 既可取到行,也可取到switch状态
            NSLog(@"行数:%ld, switch state: %u", (long)indexPath.row, cell.switchBtn.on);
        };
        return cell;
    }

Blocks 内存管理

可以参考这篇文章Objective-Block