美文网首页
block的简单理解(1)

block的简单理解(1)

作者: 火星救援 | 来源:发表于2016-03-27 00:04 被阅读48次

    一. block类型的变量的声明.

    返回值类型(^block变量名)(参数列表);

    void (^myBlock)();

    表示声明了1个block类型的变量变量名叫做myBlock

    这个myBlock变量只能存储无返回值无参数的代码段.

    void (^myBlock1)(int num1,int num2);

    表示声明了1个block类型的变量叫做myBlock1

    这个myBlock1变量之中可以存储无返回值带两个int类型的参数的代码段.

    int (^myBlock2)(int num1,int num2);

    二. block变量的初始化.

    2).如何写1个符合要求的代码段.

    语法:

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

    代码;

    };

    a.无参数无返回值的代码段.

    ^void(){

    NSLog(@"呵呵1");

    NSLog(@"随便2");

    };

    完全可以将这个代码段通过赋值符号存储到符合要求的block变量之中.

    void (^myBlock1)();

    myBlock1 =   ^void(){

    NSLog(@"呵呵1");

    NSLog(@"随便2");

    };

    当然完全可以在声明block变量的同时直接赋值.

    b.无返回值,有参数的代码段的书写.

    ^void(int num1,int num2){

    int num3 = nim1 + num2;

    NSLog(@"num3 = %d",num3);

    };

    void (^myBlock2)(int num1,int num2) =  ^void(int num1,int num2){

    int num3 = nim1 + num2;

    NSLog(@"num3 = %d",num3);

    };

    c.有返回值有参数的代码段的书写.

    ^int(int num1,int num2){

    int num3 = num1 + num2;

    return num3;

    };

    int (^myBlock3)(int num1,int num2) = ^int(int num1,int num2){

    int num3 = num1 + num2;

    return num3;

    };

    为block变量赋值代码段的时候,代码段必须符合block变量的返回值和参数的要求.

    否则就会报错.

    三.执行存储在block类型变量中的代码.

    1).如何执行?

    在要执行的地方加上代码:             block变量名();

    如果存储在block变量中的代码段有参数,那么给参数就可以了.

    如果有返回值,使用1个相应类型的变量接收返回值就可以了.

    6.使用block注意小点.

    1).如果代码段没有参数.那么代码段可以省略表示参数列表的小括弧.

    void (^myBlock)() = ^void{

    NSLog(@"呵呵");

    };

    2).如果声明block变量的时候,要求代码块带参数.那么在声明block变量的时候.可以只写参数类型,省略参数名称.

    但是代码段是必须要写参数名字的.

    void (^myBlock)(int,int) = ^void(int num1,int num2){

    NSLog(@"%d + %d = %d",num1,num2,num1+num2);

    };

    3).代码段的返回值类型可以省略.

    int (^myBlock)(int,int) = ^(int num1,int num2){

    return num1 + num2;

    };

    如果代码段没有指定返回类型.那么这个代码段的返回值类型就是return回去的数据的类型.

    如果没有return那么这个代码段就的返回值就是void.

    void (^block1)() = ^{

    .....

    };

    7.使用typedef将复杂的block定义简化.

    1).遇到的问题.

    如果我们希望定义1个无返回值无参数的block变量.

    void (^myBlock1)();

    如果再希望定义1个呢?

    void (^myBlock2)();

    如果再希望定义1个呢?

    void (^myBlock2)();

    ...........

    你有没有发现,每次定义block变量要使用好长的1段代码,忒麻烦.

    2).我们学习过typedef给已经存在的类型取1个别名.

    我们可以为1个指定要求的block取1个短别名.然后使用这个别名声明多个要求一致的block变量.

    废话不说,看例子.

    typedef void (^newType)();

    代表为返回值为void并且没有参数的block类型定义了1个别名叫做newType.

    如果我们想声明1个没有返回值并且参数的block.直接使用别名newType就可以定义.

    比如:

    newType myBlock;

    首先,myBlock是1个变量.1个block类型的变量.这个变量要求存储的代码段无返回值并且没有参数.

    所以,可以像下面这样初始化.

    myBlock = ^{

    NSLog(@"呵呵");

    };

    调用按原来的就方式就可以调用.

    myBlock();

    ------------再次举例-----------------

    typedef int (^newType)(int,int);

    代表为返回值为int类型,参数有两个int类型的参数的block类型定义了1个别名叫做newType.

    如果我们要声明1个返回值为int,并且参数是两个int类型的block变量的时候,

    就可以使用newType来直接简单声明

    newType sumBlock = ^(int num1,int num2){

    return num1 + num2;

    };

    调用block

    int sum = sumBlock(10,20);

    四. block访问外部变量.

    1).全局变量.局部变量. block内部变量.重名及各自的作用域.

    2).默认情况下,block内部可以取外部的变量的值.

    但是无法修改外部变量的值.

    可以修改全局变量,但是无法修改外部的局部变量.

    3).如果允许外部变量的值在block内部可以被修改,那么就将外部变量使用__block修饰.

    默认情况下block外部的局部变量只允许在block内存的取值访问,不允许在block内部改值.

    如果就是要允许外部的局部变量可以改

    用__block来修饰外部的局部变量.

    五,block作为函数的参数

         1. block是1个数据类型. 所以block类型完全可以作为函数的参数或者返回值.

    2. block作为函数的参数.  (他的作用就是让调用者自己控制代码的实现,比如实现两个数的和与乘积)

    1). 形参就直接声明1个符合要求的block变量就可以了.如果觉得恶心,可以使用typedef简化定义.

    2). 实参代码段的要求必须要和形参的要求一致.

    如果形参是1个无返回值无参数的block 那么实参的代码段也必须要符合这个要求.

    3). 在传值的时候.

    a. 先将符合要求的代码段存储在1个block变量之中 然后再传递block变量.

    b. 也可以直接传递符合要求的代码段.

    3. block作为函数的参数可以实现的效果.

    可以让调用者传递1段代码到函数的内部. 在函数的内部执行这段代码.

    void sum(int a, int b, void(^block)(int c)){

    int sum = a + b;

    // 回调block

    block(sum);

    }

    // 调用函数

    sum(20, 10, ^(int c) {

    NSLog(@"sum=%d",c);

    });

    上面只是一个小例子,在第申明函数的内部,把求和的结果放在了block里面,相当于求和的代码块放在了block里面,当我们调用函数的时候,就可以使用这个存放在block里面的代码块。

    3. block与函数的异同

    1). 相同点: 都可以封装1段代码在其中.

    2). 不同点:

    a. block是1个数据类型. 而函数就是函数.

    b. block可以作为函数的参数传递。而函数不能直接作为参数传递.

    c. block可以嵌套.函数不能嵌套定义.

    4 ,blcok作为函数的返回值

    步骤是:1 定义一个新的blcok数据类型

                    2 新的block数据类型作为函数的返回值

                    3 调用函数

                    4 回调block 

    //相当于定义一个void类型的无参数的block数据类型    新的数据类型名为NewType

    typedef void (^NewType)();   // 第一步

    NewType test()     // 第二步

    {

    void (^block)() = ^{

    NSLog(@"哈哈哈哈哈哈哈");

    NSLog(@"呵呵呵呵呵呵呵");

    };

    return block;

    }

    // 调用函数

    NewType bType =  test();    // 第三步

    bType();    // 第四步

    再深入理解的Block,可以看下下面3篇文章,写的很好。

    http://my.oschina.net/leejan97/blog/268536

    http://my.oschina.net/leejan97/blog/262855

    http://my.oschina.net/leejan97/blog/209762

    相关文章

      网友评论

          本文标题:block的简单理解(1)

          本文链接:https://www.haomeiwen.com/subject/momdlttx.html