Objective-C之Block基本应用

Objective-C之Block基本应用

前言:本文整理了一些block的一些基础用法以及对使用场景的一些理解,如果有哪里不对,欢迎留言讨论哦~

本质

block又称之为代码段,是一个可以存储代码的数据类型。

block基本使用
// 语法
// 返回值类型 (^block变量名称)(参数列表);

// 栗子1:一个无返回值,无参数的block
void (^myBlock)();

// 栗子2:有返回值,无参数的block
int (^myBlock)();

// 栗子3:有返回值,有参数的block
int (^myBlock)(int num1,int num2);
block的简写

1.如果写的代码段没有返回值,那么代码段的返回值可以省略
注意:是代码段的返回值,而不是声明block的返回值

// ✅ 正确形式
//省略前
void (^myBlock)(int num) = ^void(int num){
    ......
};
//省略后
void (^myBlock)(int num) = ^(int num){
    ......
};
    
// ❎ 错误形式
(^myBlock)(int num) = ^void(int num){
    ......
};

2.如果写的代码段没有参数,那么代码段的小括号可以省略
注意:是代码段的小括号,而不是声明block的小括号

// ✅正确形式
// 省略前
int (^myBlock)() = ^int(){
    ......
};

// 省略后
int (^myBlock)() = ^int{
    ......
};

// ❎错误形式
int (^myBlock) = ^int(){
    ......
};

3.结合1、2
既没有返回值,也没有参数的block,则可以将返回值与参数列表的小括号全部省略掉

// 省略前
void (^myBlock)() = ^void(){
    ......
};

// 省略后
void (^myBlock)() = ^{
    ......
};

4.声明block变量的时候,如果有指定参数,可以只写参数的类型而不写参数的名称
注意:这里说的是声明,而不是代码段

// 省略前
int (^myBlock)(int num) = ^int(int num) {
    ......
};

// 省略后
int (^myBlock)(int) = ^int(int num) {
    ......
};

5.block的返回值
无论代码段是否有返回值,在写代码段的时候都可以省略,系统会自动的确认返回值的类型。
如果代码段中没有返回任何数据,系统会认为这个代码段没有返回值
如果代码中有返回数据,返回的数据是什么类型,那么系统会认为这个代码段的返回值就是什类型

// 举个栗子,下面的代码块返回值类型为int
int (^myBlock)() = ^ {
    return 1;
};

6.建议
虽然简写可以少些一写代码,但是在多人协同开发时,还是建议完整的定义一个block,有利于提高代码的可阅读性。

typedef定义block
// 语法
//typedef 返回值类型 (^block名称)(参数列表);

// 举个栗子
typedef int (^myBlock)(int num1, int num2);
block访问外部变量

1.在block内部可以读取定义在外部的变量的值,包括外部的局部变量和全局变量。
2.在block内部可以修改定义在外部全局变量的值,但是不可以修改定义在外部的局部变量。
3.如果想在在block内部修改定义在外部的局部变量,需要在外部变量的定义前加上关键字__block。

int num1 = 100; // 全局变量
typedef void (^myBlock)();  

int main() {
    int num2 = 200;
    __block int num3 = 300;
    
    myBlock blockTest = ^void() {
        // 读取
        NSLog(@"%d",num1);  // 打印100
        NSLog(@"%d",num2);  // 打印200
        NSLog(@"%d",num3);  // 打印300
        
        // 修改
        num1++; // num1 = 101
        //num2++; // 解开注释会报错
        num3++; // num3 = 301
        
        NSLog(@"%d",num1);  // 打印101
        NSLog(@"%d",num3);  // 打印301
    };
    
}
block作为方法参数

block作为函数参数的直观作用:被调用的方法可以按照调用者的意愿完成某些逻辑
举个栗子:
现在有一个数组@[@Korean,@“China”,@“America”],需要排序。

小红:我想按照首字母升序排序
小明:我想按照每个元素的长度升序排序
这时我们就可以实现一个方法,参数为不同的排序规则

// 用于存储排序方法的代码段
typedef NSArray*(^sortBlock)(NSArray *);

int main(){
    // 字符串数组
    NSArray *arr = @[@"Korean",@"China",@"America"];

    // 小红的方法
    sortBlock xiaohongBlock = ^NSArray*(NSArray *){
        return @[@"America",@"China",@"Korean"];
    };
    
    // 小明的方法
    sortBlock xiaomingBlock = ^NSArray*(NSArray *){
        return @[@"China",@"Korean",@"America"];
    };
    
    return 0;
}

// 排序方法
- (void)showWithArr:(NSArray *)arr withMySortBlock:(sortBlock) myBlock{
    NSInteger nLen = [arr count];
    NSArray *afterSortArr = myBlock(arr);
    
    for (int i = 0; i < nLen ;i++) {
        NSLog(@"%@",afterSortArr[i]);
    }
}


输出结果:

小红:
America
China
Korean

小明:
China
Korean
America

注:为方便理解,上述代码中并没有写具体的算法,而是直接将排序好的数组返回。

block作为方法返回值
int main(){
    void(^myBlock)(void) = [self show];
    myBlock();
    
    return 0;
}

-(void(^)(void))show{
    return ^void(){
        NSLog(@"block 作为函数返回值");
    };
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值