城之内

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

 

Blocks 是一个带有自动变量值的匿名函数

1 block语法

完整形式的block语法与一般c语言函数定义,有两点不同

(1)没有函数名

(2)带有 "^"

c:

  int func(int a)

  {

    return a;

  }

block:

  ^int (int a)

  {

    return a;

  }

block语法的BN范式: ^返回类型 参数列表 表达式 ^ int (int count){...};

可以省略为 ^ 参数列表 表达式^ (int count){...};

如果没有参数可以省略为 ^ 表达式^ {...};

 

2 block类型变量

c语言中函数指针表达方式:

int func(int count)

{...}

int (*funcptr)(int count);

 

block语法将"*" 换为 "^"

int (^blk)(int) = ^ (int count){...};

int (^)(int)为block类型 blk为变量名

 

赋值操作

int (^blk1)(int) = blk 将blk赋值给新变量blk1

 

为了方便记述可以用c中方法typedef来解决该问题

typedef int (^blt_t)(int); 定义了一个block类型

blt_t myBlock = ^(int count){...};

int (^myBlock)(int) = ^(int count){...};

 

blt_t myBlock; => int (^myBlock)(int) ;

以上2个表达式是等价的.

注意:typedef int (^blt_t)(int); 和 int (^blt_t)(int); 不一样前者是一个类型,后者是一个类型变量要区分

 

当用于函数参数的时候可以以下方式:

1 -(void)setCallBack:(void (^)(int data)) block

2 typedef int (^blt_t)(int);

  -(void)setCallBack:(blt_t) block

 

3 截获自动变量

前面介绍了匿名函数,这节介绍什么是带有自动变量值。

在block表达式中截获所有的自动变量的值,即保存该自动变量的瞬间值,即使改写block中使用的自动变量也不会影响block执行时自动变量的值。

    int n = 10;

    void (^testBlock)() = ^()

    {

        NSLog(@"block :%d", n);

    };

    n = 20;

    testBlock(n);

这里block截获了n得瞬间值10,虽然在调用block之前修改了n的值,但是打印出来的还是10.

 

__block 说明符

想在block表达式中修改block以外的自动变量,需要在该自动变量前面加上__block说明符

    __block int n = 10;

    void (^testBlock)() = ^()

    {

        NSLog(@"block :%d", n);

    };

    n = 20;

    testBlock(n); 打印出来20.

 

4 OC对象瞬间值

int val = 0;

void (^blk)(void) = ^{val = 1;}; 如果在block中修改自动变量会产生编译错误。

那如果用oc对象呢?

id array = [[NSArray alloc]init];

void (^blk)(void) = ^{

  id obj = [[NSObject alloc]init];

  [array addObject:obj];

}

这是没问题的,但是如果你要修改自动变量array的值也会产生编译错误。这个有点像c语言中将一个const指针当参数传到函数中,虽然不能修改指针的值但是可以修改指针指向的值。

 

posted on 2015-05-19 08:38  城之内  阅读(233)  评论(0编辑  收藏  举报