【Objective-C】代码块(Block)

一、Block是什么?

1. 是代码段,苹果推荐的类型,效率高,在运行中保存代码。用来封装和保存代码,有点像函数,block可以在任何时候执行;

2. 代码块本质上是和其他变量类似。不同的是,代码块存储的数据是一个函数体。使用代码块是,你可以像调用其他标准函数一样,传入参数数,并得到返回值。

    脱字符(^)是块的语法标记。按照我们熟悉的参数语法规约所定义的返回值以及块的主体(也就是可以执行的代码)。

   定义代码块语法:

  块类型   块对象  =  ^(参数列表){  夸函数体   };

void(^myblock)() = ^(){  // 无返回值 无参数 =右边的()可以省略
        NSLog(@"-------");
        NSLog(@"-------");
    };
    
int (^sumblock)(int, int) = ^(int a, int b) {  // 有返回值 有参数
        return a + b;
    };
   下图是如何把块变量赋值给一个变量的语法讲解

    按照调用函数的方式调用块对象变量就可以了:
    int result = myBlock(4); // result是 28

3. 和函数的相似性:

    1)可以保存代码;

    2)有返回值

    3)有形参

    4)调用方式一样

4. 标识符:^

二、基本使用

1. 定义block变量

    Int (^SumBlock)(int,int);//有参数,返回值类型为int

    Void (^MyBlock)()//无参数,返回值类型为空

2. 利用block封装代码

        // 利用block封装代码
        // 1.接受两个参数
        int (^MyBlock1)(int, int) = ^(int a, int b) {
            return a + b;
        };
        
        // 2.无参数形式
        int (^MyBlock2)() = ^() {
            return 20;
        };
        
        // 3.无参数的省形式
        // 2.无参数形式
        int (^MyBlock3)() = ^ {
            return 20;
        };
3. Block 访问外部变量

    1)Block内部可以访问外部变量;

    2)默认情况下,Block内部不能修改外部的局部变量

    3)给局部变量加上__block关键字(两个下划线哦),则这个局部变量可以在block内部进行修改。

如:

void test2() {
    __block int c = 19;
    
    // 声明一个block变量
    // 可以使用无数多个变量进行调用
    MySum sum = ^(int a, int b) {
        // 如果外部的变量已经用__block关键字修饰,就可以在block内部修改这一个变量
        c = 19;
        return  a + b;
    };
    NSLog(@"%i", sum(10, 10));
}
4. 利用 typedef 定义 block 类型 ( 和指向函数的指针很像 )。关于tepedef的作用后面的的文章有介绍typedf讲解

    Typedef int(^MyBlock)(int , int);

    以后就可以利用这种类型来定义block变量了。----使用这个好处就是:可以使用无数多个变量进行调用(如下面定义了两个变量),传统的方式只能定义一个变量

    MyBlock a, b; 

    a = ^(int a,int b){return a-b;};

    MyBlock b2 = ^(int n1,int n2){return n1*n2;}

三、拓展案例

1. 参数是NSString* 的代码块

 void (^print)(NSString *x);
        print = ^(NSString *str){
            NSLog(@"print:%@", str);
        };
        
        print(@"Hello World");
2. 代码在字符串数组排序
 // 字符串
        NSArray *str = [NSArray arrayWithObjects:@"abc 1", @"abc 22", @"abc 13", @"abc 0", @"abc 09", nil];
        NSComparator sort = ^(id str1, id str2) {
            return [str1 compare:str2];
        };
        
        NSArray *sortArray = [str sortedArrayUsingComparator:sort];
        NSLog(@"sortArray:%@", sortArray);
结果是:
@class关键字[598:144356] sortArray:(
    "abc 0",
    "abc 09",
    "abc 1",
    "abc 13",
    "abc 22"
)
3. 代码块要想递归调用,代码快变量必须要是全局变量或者是静态变量,这样程序启动的时候代码块变量就初始化了,就可以递归调用
static void (^ const blocks)(int) = ^(int i)  
{  
    if (i > 0) {  
        NSLog(@"num:%d", i);  
        blocks(i - 1);  
    }  
};  
blocks(3); 
4.在代码块中使用局部变脸和全局变量
int global = 1000;  
int main(int argc, const char * argv[])  
 {  
      @autoreleasepool {  
         void(^block)(void) = ^(void)  
         {  
            global++;  
             NSLog(@"global:%d", global);  
         };  
         block();  
         NSLog(@"global:%d", global);  
     }  
     return 0;  
 }  
局部变量要想再代码块中能够更改的话需要在block里面添加一个__(两个下划线)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值