美文网首页iOS Developer
Block语法用法简记

Block语法用法简记

作者: 沈冰忱 | 来源:发表于2016-08-23 16:11 被阅读594次

    Block 语法

    Block字面量

    ^ [return type] (argument list) {
      expressions
    }
    

    可以省略return type

    ^ (argument list) {
      expressions
    }
    

    当return type和参数都为空时

    ^void (void) {
      printf("Blocks\n");
    }
    ^{
      printf("Blocks\n");
    }
    

    Block类型变量

    Function变量

    int func(int count)
    {
      return count + 1;
    }
    int (*funcptr)(int) = &func;
    

    Block 变量

    int (^blk)(int);
    和其它C语言变量一样,Block变量能作为:

    • Automatic variables, atuo变量
    • Function arguments,函数参数
    • Static variables,静态变量
    • Static global variables,全局静态变量
    • Global variables,全局变量

    int (^blk)(int) = ^(int count) { return count + 1;};

    int (^blk1)(int) = blk;
    int (^blk2)(int);
    blk2 = blk1;
    

    Block类型可以作为函数为参数

    void func(int (^blk)(int)) 
    {
    }
    

    Block也可以作为函数的返回值

    int (^func()(int)) {
      return ^(int count){return count + 1;};
    }
    

    用typedef简化Block类型变量的使用

    typedef int (^blk_t)(int);
    
    /* original
    void func(int (^blk)(int)){...}
    */
    void func(blk_t blk){...}
    
    /* original
    int (^func()(int)){...}
    */
    blk_t func(){...}
    

    执行Block

    // execute func 
    int result = (*funcptr)(10);
    
    // execute block
    int result = blk(10);
    int func(blk_t blk, int rate) {
      return blk(rate);
    }
    

    Block指针

    typedef int (^blk_t)(int);
    blk_t blk = ^(int count){return count + 1;};
    blk_t *blkptr = &blk;
    (*blkptr)(10);
    

    获取 automatic变量

    当 automatic 变量被Block获取时, 该变量在Block中是只读的 read-only. 你不能修改它.
    但是如是获取的automatic变量是Objective-C对象呢?看下面代码:

    id array = [[NSMutableArray alloc] init];
    void (^blk)(void) = ^{
      id obj = [[NSObject alloc] init];
      [array addObject:obj];
    };
    

    在C语言层上,Block捕获的是NSMutableArray对象的结构体的指针。你可以修改该指针指向的对象的内容,但不能修改这个指针本身,否则编译器会报错(下面代码)。

    id array = [[NSMutableArray alloc] init]; 
    void (^blk)(void) = ^{
      array = [[NSMutableArray alloc] init]; 
    };
    

    为了能够修改捕获的auto变量, 你需要用__block来修饰你的auto 变量。

    __block id array = [[NSMutableArray alloc] init]; 
    void (^blk)(void) = ^{
      array = [[NSMutableArray alloc] init];
    };
    

    另外,当使用C数组时,请使用数组的指针。

    const char text[] = "hello";
    void (^blk)(void) = ^{
      printf("%c\n", text[2]); 
    };
    

    上面代码看上去,没任何问题,事实上,会产生编译错误:

    error: cannot refer to declaration with an array type inside block printf("%c\n", text[2]);
    ^
    note: declared here
    const char text[] = "hello";
    ^

    就是说不能在Block中使用数组,用数组的指针代替:

    const char *text = "hello"; 
    void (^blk)(void) = ^{
      printf("%c\n", text[2]); 
    };
    

    这样就没问题了。

    相关文章

      网友评论

        本文标题:Block语法用法简记

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