天天看点

IOS中 Block简介与用法

block的简介

个人觉得,block感觉和function有点像,不同的是,函数不可以当做参数进行传递,但是block可以当做参数进行传递,而且block也可以存取一个scope的值。

block的定义

定义:^(参数列表){实现方法}

block的实体开头是^,接下来是参数列表(float a,int b,int c),接下来是实现方法{return a+b+c};当然如果没有参数的话,你可以写成^(void){};或者写成^{};

例子:

**

  • 由于block是叙述性语言,最后必须加上”;”,以为block是物体实体。
  • 而且请加上{}和^

**

block的Block Pointer

可能大家觉得郁闷的是,为什么block没有返回类型的呢?当然block也有类似函数的先声明性质。

Block Pointer 定义

回传值(^名字)(参数列);

具体使用:

//声明一个block pointer,其中实现名为size,指向int a,int b。
int ^(size)(int a,int b);
//实现block的实例
size =^(int a,int b){return a*b};
//调用size实例
int result =size(,);
//输出数据
printf(@"%d",result);
           

block pointer的函数参数调用

//函数声明
void count(int ^(size)(int a,int b));
//定义一个名叫size的block pointer的变量
int ^(size)(int a,int b) = ^(int a,int b){return a+b;};
//调用函数
count(size);
           

进行缩减的话

c语言的写法

count(^int(int a,int b){return a+b;}参数名);
           

OC语言的写法为:

-(void)count:(int ^(int a ,int b))size;

  • OC中(int ^(int a,int b))就是我们平时见到的修饰类型
  • size也就是参数名

变量的存取

  1. 自动变量
{  
    int outA = ;  
    int (^size)(int) = ^(int a){ return outA + ;};  
    //block里面可以读取同一类型的outA的值  
    outA = ; 
    int result = size();  // result is 11  
    NSLog(@"result=%d", result);  
}
           

可能会有人问答案为什么不是8呢?

**

  • block 在实现时就会对它引用到的它所在方法中定义的栈变量进行一次只读拷贝,然后在 block 块内使用该只读拷贝;换句话说block截获自动变量的瞬时值
  • 或者block捕获的是自动变量的副本。(block捕获变量的机制更像是函数按值传递)

    就是说block实例操作中,并没有将outA = 5; 这个操作给copy进去。

**

2. 全局变量、静态变量、全局静态变量

{  
    static int outA = ;  
    int (^myPtr)(int) = ^(int a){return outA + a;};  
    outA = ;  
    int result = myPtr();  //result的值是8 
    NSLog(@"result=%d", result);  

}  
           

可能会有人问答案为什么是8呢?

**

  • block 变量其实是一个结构体对象,拷贝的是指向该结构体对象的指针。
  • 静态变量属于类的,不是某一个变量。由于block内部不用调用self指针。所以block可以调用。

**

3. 修改自动变量

有人会问如果进行更改自动变量的呢?

答案就是:使用使用__block修饰符

__block int val = ;  
void (^blk)(void) = ^{printf("val=%d\n",val);};  
val = ;  
blk();
           

上面的代码,跟第一个代码段相比。只是多了一个__block修饰符。但是输出结果确是2了。

__block 变量的内部实现要复杂许多,__block 变量其实是一个结构体对象,拷贝的是指向该结构体对象的指针。

关于block的变量总结

**

  • 不能修改自动变量的值是因为:block捕获的是自动变量的const值,名字一样,不能修改
  • 可以修改静态变量的值:静态变量属于类的,不是某一个变量。由于block内部不用调用self指针。所以block可以调用。

**

4.内存管理

用这个表格来表示。捕获变量包括仅仅读取变量和__block这种写变量,两种方式(其实结果是一样的)

IOS中 Block简介与用法

在ARC下:似乎已经没有栈上的block了,要么是全局的,要么是堆上的

在非ARC下:存在这栈、全局、堆这三种形式。

参考文章:

http://blog.csdn.net/enuola/article/details/8674063

http://blog.csdn.net/hherima/article/details/38586101