Block语法用法简记

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基础回顾 1.什么是Block? 带有局部变量的匿名函数(名字不重要,知道怎么用就行),差不多就与C语言...
    Bugfix阅读 6,804评论 5 61
  • iOS面试小贴士 ———————————————回答好下面的足够了------------------------...
    不言不爱阅读 2,014评论 0 7
  • 一、Objective-C发展史 Objective-C从1983年诞生,已经走过了30多年的历程。随着时间的推移...
    没事蹦蹦阅读 5,909评论 12 34
  • 2.1 Blcoks概要 2.1.1 什么是Blocks Blocks是C语言的扩充功能——“带有自动变量(即局部...
    SkyMing一C阅读 2,396评论 6 18
  • Blocks Blocks Blocks 是带有局部变量的匿名函数 截取自动变量值 int main(){ ...
    南京小伙阅读 974评论 1 3