IOS中的Block的使用

/*

 

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

 

 

 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值