zoukankan      html  css  js  c++  java
  • 代码块(block)的使用

    Objective-C语法之代码块(block)的使用

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

    脱字符(^)是块的语法标记。按照我们熟悉的参数语法规约所定义的返回值以及块的主体(也就是可以执行的代码)。下图是如何把块变量赋值给一个变量的语法讲解:

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

    Ios4已经直接支持blocks,很有必要学习一下。

    在ios,blocks是对象,它封装了一段代码,这段代码可以在任何时候执行。Blocks可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。它和传统的函数指针很类似,但是有区别:blocks是inline的,并且它对局部变量是只读的。

    Blocks的定义:

             int (^Multiply)(int, int) = ^(int num1, int num2) {return num1 * num2;};

    定义了一个Multiply的blocks对象,它带有两个int参数,返回int。等式右边就是blocks的具体实现,注意{}blocks体里的;。

    Blocks可以访问局部变量,但是不能修改。

                  int multiplier = 7;

         int (^myBlock)(int) = ^(int num) {

             multiplier ++;//编译报错

             return num * multiplier;

         };

    如果要修改就要加关键字:__block

             __block int multiplier = 7;

         int (^myBlock)(int) = ^(int num) {

             multiplier ++;//这样就可以了

             return num * multiplier;

         };

    作为函数的参数,blocks某种意义上替代了回调函数或者delegate。当函数调用了,假设某个事件触发,这时blocks里的内容就会运行。这样有利于代码的整合和阅读,你不需要到处去实现委托方法了。

    系统API中已经有很多支持blocks参数了

    • Completion handlers
    • Notification handlers
    • Error handlers
    • Enumeration
    • View animation and transitions
    • Sorting

    1、参数是NSString*的代码块

     void (^printBlock)(NSString *x);  

    1. printBlock = ^(NSString* str)  
    2. {  
    3.     NSLog(@"print:%@", str);  
    4. };  
    5. printBlock(@"hello world!");  
    运行结果是:print:hello world!

    2、代码用在字符串数组排序

    1. NSArray *stringArray = [NSArray arrayWithObjects:@"abc 1", @"abc 21", @"abc 12",@"abc 13",@"abc 05",nil];  
    2. NSComparator sortBlock = ^(id string1, id string2)  
    3. {  
    4.     return [string1 compare:string2];  
    5. };  
    6. NSArray *sortArray = [stringArray sortedArrayUsingComparator:sortBlock];  
    7. NSLog(@"sortArray:%@", sortArray);  
    运行结果:sortArray:(

        "abc 05",

        "abc 1",

        "abc 12",

        "abc 13",

        "abc 21"

    )

    3、代码块的递归调用

    代码块想要递归调用,代码块变量必须是全局变量或者是静态变量,这样在程序启动的时候代码块变量就初始化了,可以递归调用

    static void (^ const blocks)(int) = ^(int i)

    {

        if (i > 0) {

            NSLog(@"num:%d", i);

            blocks(i - 1);

        }

    };

    blocks(3);

      

    运行打印结果:

    num:3

    num:2

    num:1

    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;

    }

     

    运行打印结果:

    global:1001

    global:1001

    而局部变量可以使用,但是不能改变。

    1. int
       local = 500;  
    2. void(^block)(void) = ^(void)  
    3. {  
    4.       local++;  
    5.     NSLog(@"local:%d", local);  
    6. };  
    7. block();  
    8. NSLog(@"local:%d", local);  
    在代码块中改变局部变量编译不通过。怎么在代码块中改变局部变量呢?在局部变量前面加上关键字:__block

     __block int local = 500;

     void(^block)(void) = ^(void)

    {

        local++;

        NSLog(@"local:%d", local);

    };

    block();

    NSLog(@"local:%d", local);

     

    运行结果:local:501

    local:501

  • 相关阅读:
    bzoj1014: [JSOI2008]火星人prefix
    bzoj1934: [Shoi2007]Vote 善意的投票&&bzoj2768:[JLOI2010]冠军调查
    bzoj2705: [SDOI2012]Longge的问题
    bzoj4653: [Noi2016]区间
    bzoj2456: mode
    bzoj5018: [Snoi2017]英雄联盟
    关于树论【左偏树】
    caioj1522: [NOIP提高组2005]过河
    caioj1421&&hdu2167: [视频]【状态压缩】选数
    Linux下全局安装composer方法
  • 原文地址:https://www.cnblogs.com/chenhaosuibi/p/3440705.html
Copyright © 2011-2022 走看看