• iOS指向函数的指针和block


      一:block基础知识


    block基础知识

    基本概念:block是用来保存一段代码的;^:是block得标志  好比*:是指针的标志

      特点:1:保存一段代码;

         2:可以有参数和返回值;

         3:可以作为函数的参数传递;

       与代码块的区别,代码块里的代码会自动执行,block中代码要手动调用;

    二:普通数据类型、指向函数的指针、block的定义的类比


    1:基本数据类型:

      例如:int a = 10; 

      格式:数据类型  变量名 = 值;

    2:指向函数的指针:可以仿照上边基本数据类型的定义

      例如:void (*p)() = function;    (funciton是某个定义好的函数) 

      格式:函数类型  *指针变量名 = 函数名;

         说明:由于p指针是指向函数的,所以(*p)()中的红色小括号必须有,因为函数本身是要参数的,即使没有参数也要写();

      如果p指向的函数有参数:int (*pp)(int, int) = sum;

      调用指向函数的指针:

         无参:p();  

         有参:int sum = pp(2,3);

    3:block的定义和使用,和指向函数的指针格式很像

      例如:void (^firstBlock)() = ^(){...代码...};   说明:蓝色的小括号可以不写,有参数的时候必须写

      格式:block类型  ^block名称 = ^{代码段};

      有参数block:int (^multiBlock)(int, int) = ^(int a, int b){

                   return a * b;

               };

      调用block:无参:firstBlock()

             有参:int result = multiBlock(2, 3);

      

    // 备注:指向指针的函数和block,可以像基本数据类型一样可以分步定义 :
    int (^multiBlock)(int, int);
        
        multiBlock = ^(int a, int b){
            return a * b;
        };

    示例代码:

     1 // 函数定义
     2 int sum(int a, int b)
     3 {
     4     NSLog(@"a+b=%d", a + b);
     5     return 2;
     6 }
     7 
     8 void logSome()
     9 {
    10     NSLog(@"我是void型的输出函数");
    11 }
    12 
    13 int main()
    14 {
    15     /***   1:基本数据类型的定义 ***/
    16     int a = 10;
    17     // 1.1先定义 后赋值
    18     int b;
    19     b = 20;
    20     
    21     /***   2:指向了函数的指针 ***/
    22     
    23     // 2.1:指向有参数的sum(int a, int b)函数
    24     int (*p)(int, int) = sum;
    25     // 2.2:指向无参数的函数logSome()函数
    26     void (*logP)() = logSome;
    27     
    28     // 调用指向函数的指针函数
    29     p(2, 3);
    30     logP();
    31     
    32     /***   3:block定义和使用 ***/
    33     
    34     // 3.1:没有参数的block定义
    35     void (^firstBlock)() = ^{
    36         
    37         NSLog(@"注意:(^multiBlock)(),这里的小括号必须写,不管有没有参数");
    38         
    39         NSLog(@"而后边的" ^(){ "的小括号可以不写");
    40     };
    41     
    42     // block的调用
    43     firstBlock();
    44     
    45     // 3.2 带参数和有返回值的block
    46     int (^multiBlock)(int, int) = ^(int a, int b){
    47         return a * b;
    48     };
    49     
    50     // 调用block
    51     int result = multiBlock(2, 3);
    52     NSLog(@"%d", result);
    53     
    54 }

    三:利用typedef 定义的block类型


     利用typedef可以将繁琐的block定义简单化

      例如:typedef void (^Myblock)(); 然后可以用Myblock类型 创建一个block,创建的格式像类创建对象

    // 利用typedef定义block类型
    typedef void (^Myblock)();
    
    int main()
    {
        // 利用自定义的block类型创建一个block
        Myblock myblock = ^{
            NSLog(@"");
        };
        
    }

    四:block和指向函数的指针作为函数参数


    1:示例代码:

    // block作为函数的参数
    void test4(void(^mb)())
    {
        mb(); // 这里要手动调用参数block
    }
    
    int main()
    {
    
        // 调用函数 同时给参数mb赋值一段代码
        test4(^{
            NSLog(@"block输出");
        });
        
    }

    2:利用typedef可以将繁琐的block简单后,这个block就成为了一种类型,可以像类一样创建对象,指向函数的指针同样可以

    // 利用typedef定义定义指向函数的指针
    typedef void (*Tp)();
    // 利用typedef定义block
    typedef void (^Myblock)();
    
    void logSome()
    {
        NSLog(@"我是void型的输出函数");
    }
    
    // 指向函数的指针作为参数
    void test1(Tp p)
    {
        p();
    }
    
    // block作为函数的参数
    void test2(Myblock mb)
    {
        mb();
    }
    
    int main()
    {
        // 指向函数的指针定义
        Tp myP = logSome;
        test3(myP);
        
        // 定义block
        Myblock mb = ^{
            NSLog(@"block输出");
        };
        test4(mb);
    }
  • 相关阅读:
    python变量和作用域
    模块
    装饰器
    转git取消commit
    RTP
    ffmpeg编译
    win7开启wifi
    LIVE555
    【FFmpeg】ffplay播放rtsp视频流花屏问题
    Windows下编译SDL
  • 原文地址:https://www.cnblogs.com/cxbblog/p/3841226.html
Copyright © 2020-2023  润新知