iOS Developer

Block语法用法简记

2016-08-23  本文已影响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变量能作为:

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]); 
};

这样就没问题了。

上一篇下一篇

猜你喜欢

热点阅读