10 iOS底层原理 - Block基本用法

在研究Block本质之前呢,先简单说下,block的语法。

一,Block语法

1. 标准声明与定义
返回值1(^block名)(参数列表1) = ^返回值2(参数列表2){
     实现
};

可以拆开来写:

1>声明部分
// 声明部分:
返回值1(^block名)(参数列表1);

参数说明:

返回值1:表示block声明的返回值 返回的对象/关键字等(可以是void,并省略,这个返回值一般不省略);
block名:block名称;
参数列表1:表示参数的类型(可以是void,并省略),可以是多个参数,变量可以省略.
2> 定义部分,匿名block
^返回值2(参数列表2){
      实现
};

参数说明:

返回值2:表示block定义的返回值 返回的对象/关键字等(可以是void,并省略);
参数列表2:表示参数的类型(可以是void,并省略),可以是多个参数.
3> 调用

我们一般使用的时候,是将定义部分的block赋值给声明的block

// 简单的使用
block名();
2. 举几个例子
1> 有返回值
int(^myBolck)(int a);
myBolck = ^int(int a) {
    NSLog(@"myBolck a == %d", a);
    return a + 10;
};
int result = myBolck(20);
NSLog(@"result == %d", result);
// myBolck a == 10
// result == 30
2> 没有返回值
void(^myBlock2)(int a) = ^void(int a) {
     NSLog(@"myBolck2 a == %d", a);
};

省略相关参数

void(^myBlock2)(int) = ^(int a) {
        NSLog(@"myBolck2 a == %d", a);
};
myBlock2(40);
// myBolck2 a == 40
3> 参数类型是void
int (^myBolck3)(void) = ^int(void) {
     return 10;
};
int result3 = myBolck3();
NSLog(@"result3 == %d", result3);
// result3 == 10
4> 返回类型和参数类型都是void
void (^myBlock4)(void) = ^{
      NSLog(@"myBlock4");
};
myBlock4();
// myBlock4

回过头来再看看这个匿名block:

二,匿名block

Block实现时,等号右边就是一个匿名Block,它没有blockName,称之为匿名Block:

^返回值(参数列表) {
    实现
};

举个例子

^(int a) {
     NSLog(@"这是一个匿名block %d", a);
};
// 实现
^(int a) {
        NSLog(@"这是一个匿名block %d", a);
}(8);

三,Block的几种应用场景

1. typedef block
typedef 返回值(^block名)(参数列表);

这种用法我们也是比较常用的:

// 定义
typedef void(^SuccessBlock)(id response);
// 作为属性
@property (nonatomic, copy) SuccessBlock succBLock;
// 作为方法入参
- (void)requestSucc:(succBLock)succ;

// 使用
self.succBLock = ^(NSString *result) {
     NSLog(@"sucBLock-result%@", result);
};
self.succBLock(@"这是结果");
// sucBLock-result这是结果
2. 作为函数参数
- (void)func:(void(^)(int a))block {
    block(18);
}

// 使用
[self func:^(int a) {
    NSLog(@"testBlock - a = %d", a);
}]
// testBlock - 18
3. 局部变量
void (^block)(void) = ^(){
};
block();

四. 注意点

1> 正常block的声明
返回值(^block名)(参数列表);
void (myBlock)(int a, int b); // 这里的a和b是可以省略的
2>函数入参和返回值的声明
返回值(^)(参数列表)block名
// 定义
- (void(^)(int))testBlock2:(void(^)(int a))block;

// 实现
- (void(^)(int))testBlock2:(void(^)(int a))block {
    block(10);
    return block;
}

// 执行
void (^block4)(int) = [self testBlock2:^(int a) {
     NSLog(@"block4 == %d", a);
}];
block4(40);
// block4 == 10
// block4 == 40

以上就是block的常规使用,在下面的博客中我会介绍一下block的本质。
比方说,block的底层数据结构、block的本质、block都有哪些类型、block值捕获、__block、block的循环引用等问题。

你可能感兴趣的:(10 iOS底层原理 - Block基本用法)