免费开源的iOS开发学习平台

OC Block块:1-Block简介

block是从iOS4开始引入的一个新特性,block是对C语言的一个扩展,在Objective-C中完全支持。block在现在的iOS开发中使用越来越普遍,因为block使用起来非常强大,简单来说,block就是封装了一组代码语句的对象,可以在任何时间执行。

1、Block简介

Block在官方文档中的定义是这样的:Block块是封装工作单元的对象,是可以在任何时间执行的代码段。其本质上是可移植的匿名函数,可以作为方法和函数的参数传入,可以从方法和函数中返回。

Block是对C语言的一种扩展,它并未作为标准的ANSI C所定义的部分,而是由苹果公司添加到语言中的。Block看起来更像是函数,可以给Block传递参数,Block也可以具有返回值。

在iOS4以后,越来越多的系统框架的API在使用Block。苹果对于Block的使用主要集中在如下几个方面:

  • 完成处理–Completion Handlers
  • 通知处理–Notification Handlers
  • 错误处理–Error Handlers
  • 枚举–Enumeration
  • 动画与形变–View Animation and Transitions
  • 分类–Sorting
  • 线程管理:GCD/NSOperation

2、Block的定义与调用

块是以插入字符^开头,后面的一个括号()内表示块所需要的参数,最后面的大括号{}中是块主体,最后以分号;结束。如下面代码所示:

^(int inputNum) {
    NSLog(@"printBlock Called!");
    return inputNum;
};

同时,也可以将这个块赋值给一个变量printBlock,声明方式如下。其中,变量printBlock就是指向代码块的指针

返回值类型 (^block名称)(参数类型, 参数类型, ...) = ^(参数类型 参数名称, 参数类型 参数名称, ...) {
 //block体(封装的代码)
};

如下示例,我们定义了一个变量printBlock,这个变量指向一个Block,Block位于等号右边,这个Block执行时,需要提供一个int型的参数,同时会返回一个int型的返回值。

int (^printBlock)(int) = ^(int inputNum) {
    NSLog(@"printBlock Called!");
    return inputNum;
};

当需要调用已经定义的block时,可以使用如下方式,和函数调用十分类似。

int i = printBlock(100);

3、把Block声明为类的属性

由于Block就是一个存储了一段代码的对象,因此,也可以把Block设置为某个类的属性。Block属性与其他类型的属性,如:NSString、NSArray,没有什么本质区别,都可以使用点语法来对属性进行取值和赋值。

@property (nonatomic, copy) 返回值类型(^Block名称)(参数类型);

注意:当声明一个block类型的属性时,需要使用属性关键字copy

在下方的示例代码中,添加了两个Block属性,在程序运行过程中,为两个Block属性进行赋值,即指定了一段代码,然后调用执行Block中的代码。

  • 新建一个Single View Application工程,在ViewController.h文件中,声明两个Block属性
@interface ViewController ()
@property(copy) void (^blockProperty) (void); //无参数、无返回值
@property(copy,nonatomic) void (^blockPropertyWithInput) (int); //有参数、无返回值
@end
  • 在ViewController.m文件中,通过点语法为两个Block属性赋值,然后再调用Block中的代码。
- (void)viewDidLoad {
    [super viewDidLoad];
    //blockProperty:给block赋值,即指定一段代码
    self.blockProperty = ^{
        NSLog(@"blockProperty被调用!");
    };
    //调用/执行block中的代码
    self.blockProperty();
    
    //blockPropertyWithInput:给block赋值,即指定一段代码
    self.blockPropertyWithInput = ^(int i){
        NSLog(@"blockPropertyWithInput被调用! 输入的参数值是 %d", i);
    };
    //调用/执行block中的代码
    self.blockPropertyWithInput(150);
}

运行结果:

示例代码

https://github.com/99ios/5.1.1