IOS中的Block的使用

来源:互联网 发布:消防知识知多少手抄报 编辑:程序博客网 时间:2024/04/29 00:30

/*

 

 0. blockiOS开发中大量频繁的使用到.

 

 

 1.我们说,OCC的基础之上新增了一些数据类型.

   

    BOOL

    Boolean

    id

    class

    SEL

    nil

    block

 

   除了block类型.其他的类型我们都全部讲过了.

 

 

 2. block是个数据类型.

 

    int float double.....都是用来声明变量用这个变量来存储数据.

 

    int

    float

    ......

 

   既然block1个数据类型.那么我们就可以声明block类型的变量.

   那么这个block类型的变量中是存储什么样的数据的呢?

 

   是的.用来存储1段代码.这段代码可以有参数,也可以有返回值.

 

    myBlock: block类型的.

 

   NSLog(@"hhahahah1");NSLog(@"hhahahah2");NSLog(@"hhahahah3");

 

   可以通过这个变量来执行存储在变量中的代码.

 

   听来和函数很像.

 

 

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

 

   我们说过,block类型的变量是用来保存1段代码的.这段代码可以有参数,也可以返回值.

 

    1block变量中不是任意的代码段都可以存储的.

   是有限定的.

 

   所以.block变量必须要指定这个变量存储的代码段的参数描述和返回值描述.

 

 

   声明block变量的时候,必须要指定这个block变量能够存储什么样的代码段.

   这个代码段是否有返回值什么类型的代码段是否有参数以及参数的类型.

 

 

    myBlcok: void (int num1,int ,num2)

 

 

    block变量存储的代码段是也有要求的.不是任何代码段都可以存储,代码段的参数和返回值必须要与block变量的描述一致.

 

   声明block变量的语法格式:

 

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

 

    void (^myBlock)();

   表示声明了1block变量,叫做myBlock.这个变量是用来存储1段代码的.这段代码不要求有参数,也没有返回值.

 

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

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

   这个变量是用来存储1段代码的.这段代码要求有两个参数都是int类型的,这段代码还得有1个返回值.

 

 

 

 

 

 

 

 

 4. block变量的初始化.

   

   初始化1block变量很轻松.只要将符合block变量要求的代码段赋值给其就可以了.

   那么关键的问题是,如何描述1个代码段.

 

   描述代码段的格式:

 

    ^代码段的返回值类型(参数列表){

       代码段;

    };

 

   比如如下:

   

    ^void(){

        NSLog(@"这是1个代码段1");

        NSLog(@"这是1个代码段2");

    };

 

   这描述的是1个无参数,无返回值的代码段,那么我们就可以将这个代码段赋值给1个无返回值要求和无参数要求的block变量.

 

    void (^myBlock)();

 

    myBlock = ^void(){

        NSLog(@"这是1个代码段1");

        NSLog(@"这是1个代码段2");

    };

 

   此时,myBlock变量中就存储了这段代码.

 

 

    又再比如

    ^void(int num1,int num2){

        int num3 = num1 + num2;

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

    };

   这描述的是带2int类型的参数的.无返回值的代码段。

   那么我们可以将这个代码段赋值给1个无返回值要求并且参数是两个int类型的block变量.

   

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

 

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

        int num3 = num1 + num2;

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

    };

 

   此时,myBlock变量中就存储了这段代码.

 

 

   再再比如:

 

    ^int(int num1,int num2){

        int num3 = num1 + num2;

        return num3;

    };

   这描述的是带2int类型的参数的.返回值为1int类型的代码段。

   那么我们可以将这个代码段赋值给1个返回值要求为int类型的.并且参数是两个int类型的block变量.

 

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

 

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

        int num3 = num1 + num2;

        return num3;

    };

 

 

   当然了,完全可以在声明block变量的同时就使用1段符合要求的代码段初始化给这个block变量.

 

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

        int num3 = num1 + num2;

        return num3;

    };

 

 

 

 

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

        int num3 = num1 + num2;

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

    };

 

 

 

    void (^myBlock)() = ^void(){

        NSLog(@"这是1个代码段1");

        NSLog(@"这是1个代码段2");

    };

 

 

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

   

   执行存储在block变量中的代码非常简单.

 

   语法格式: block变量名(); 就可以执行存储在block中的代码.如果存储的代码段有参数那么要传递参数如果有返回值可以接收。

 

   与调用函数一样,有参数在小括弧中传递参数.有返回值声明变量接收就可以.

 

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

        int num3 = num1 + num2;

        return num3;

     };

 

    执行存储在myBlock变量中的代码.

 

     int sum = myBlock(12,100);

 

 

 6.使用block注意小点.

 

 

    总结:

     1). block1个数据类型.就可以声明变量.

     2). block类型的变量是用来存储代码段的.

     3). block变量的声明

     4).初始化block变量.

     5).初始化的时候要注意的问题.

     6).如果赋值的代码段的返回值和参数与变量的描述不一致编译器直接报错.

 

 

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

 

        void (^myBlock)() = ^void{

            NSLog(@"呵呵");

        };

 

 

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

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

 

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

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

        };

 

    3).代码段的返回值类型可以省略.但是最终在代码段中还是要返回1个符合要求的类型的数据.

 

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

            return num1 + num2;

        };

 

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

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

 

        void (^block1)() = ^{

            .....

        };

 

 

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

 

    0). typedef的作用:1个已经存在的数据类型取1个别名.

 

        typedef int AAA;

 

        int num = 12;

        AAA a = 12;

 

        unsinged long int  num = 12;

 

         typedef unsigned long NSUIntger

 

     .

 

 

   

    1).遇到的问题.

 

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

    void (^myBlock1)();

   如果再希望定义1个呢?

    void (^myBlock2)();

   如果再希望定义1个呢?

    void (^myBlock2)();

    ...........

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

 

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

   

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

 

   废话不说,看例子.

 

    typedef void (^newType)();

   

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

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

   比如:

 

    newType myBlock;

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

 

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

 

    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);

 

 

 

 8. block访问外部变量.

   

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

 

 

 

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

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

 

       外部变量:定义在block外部的变量,就叫做外部变量.

 

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

 

 

 

 

 */

 

 

/*

 1. block1个类型,这个类型的变量中存储的是1段代码.

   我们可以将1段代码存储在1个变量之中,那么我们就可以将这个变量,传过去又穿过来.

 

 

 2.所以,block可以作为函数的参数.

 

    1).这样是可以的因为block1个数据类型.

    2).声明:block变量的声明写在函数的小括弧之中.代表这个是参数.

    3).传值的时候.传递的代码段要和形参的要求一致.

 

 

   block作为函数的参数的时候可以实现的效果:

   可以将调用者的代码段传递到函数的内部去使用.

 

   调用这个函数的时候:

    1).可以声明1block变量.讲符合要求的代码段存储在变量之中,然后再传递变量.

    2).也可以直接讲符合要求的代码段传递;

 

*/

 

/*

  1. block是干嘛的?用来存储1个代码段.

  2. block1个数据类型 可以当做函数

 

  -----------------

 

 

 

  3. block可以将1段代码传递到另外1个方法的内部去使用.

 

          方法的内部就会再适当的实际调用代码块.

 

 

  4. UIKit 执行动画.

 

    

    别人写得1个方法.这个方法在执行的期间要执行你的代码

    这个时候就要求你将代码传递给这个方法.

    使用block来将代码传递给这个方法 方法的内部要去执行你的代码的时候就会去调用这个block

 

 

 

 

 */

 

 

/*

  1. block1个数据类型,可以作为函数的参数.

    必须也可以作为函数的返回值.

    

    当方法执行完毕之后,方法返回给调用者1段代码.

    调用者拿到这段代码之后就可以随时的执行.

 

 

  2. block与函数的异同.

 

    相同点:都是将1段代码进行封装.

 

    不同点: block1个数据类型.函数就是1个函数.

            block可以作为参数传递.而函数本身是不能直接作为参数的.

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

 

 

 */

0 0