您的位置:首页 > 移动开发 > Objective-C

Objective-C代码块Block详解

2015-10-25 19:41 549 查看
    block代码块是OC的一个特性,除了可执行的代码外,还可能包含变量的自动绑定(栈),或内存托管(堆)。所以一个block维护一个状态集(数据),可以在任何时候执行。block用来作为回调特别有用。

    block可以作为函数参数或者函数的返回值,而本身又可以带输入参数或返回值。在多线程,异步任务,集合遍历,接口回调等地方用得比较多。使用标识符^.。为了性能,block都是分配在栈stack上面的,它的作用域就是当前函数。

    我们来说说block和函数的相似性:

(1)可以保存代码;

(2)有返回值;

(3)有形参;

(4)调用方式一样;

下面我们使用代码来演示一下block的用法:

#import <Foundation/Foundation.h>

//声明一个闭包;

//没有返回值,没有输入参数;
void (^one) (void);

//有返回值,没有输入参数;
int (^two) (void);

//没有返回值,有输入参数;
void (^three) (int);

//有返回值,有输入参数;
int (^four) (int ,int);

int main(int argc, const char * argv[]) {
@autoreleasepool {

//定义闭包函数;
one = ^(void){
NSLog(@"执行了one");
};

two = ^(void){
NSLog(@"执行了two");
return 2;
};

three = ^(int a){
NSLog(@"执行了three");
};

four = ^(int a,int b){
NSLog(@"执行了four");
return a + b;
};

//调用闭包函数;
one();
two();
three(1);
four(2,3);

NSLog(@"%d",two());
NSLog(@"%d",four(2,3));

}
return 0;
}
输出结果如下:




     同样,我们可以在声明的时候直接定义block,示例如下:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
  @autoreleasepool {

    //我也可以直接在这里声明的时候进行定义;
    void(^block)(int a) = ^(int a){
    
      NSLog(@"%d",a);
      
    };
    
    
    block(3);
    
  }
    return 0;
}


输出结果如下:




     block非常重要的一个功能就是进行值捕获。请看一下示例代码:此时我们只能捕获num的值,不能去修改它,因为这是一个值类型,进行的是值传递。

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
@autoreleasepool {

//Block值捕获
int num = 10;
void(^myBlock)(void) = ^(void){
//我们可以在block内部访问到外部的变量,但是不能修改;
NSLog(@"num = %d",num);

};

myBlock();

}
return 0;
}


输出结果如下:




但是如果因为项目实际需要,需要在block内部修改外部变量的值,那么就可以使用__block关键字修饰变量,示例代码如下:此时的这个变量就变成了引用类型。在block内就可以修改它的值。

但是请注意,只要没对block进行copy操作,block就一直在在stack中,要想延长block的作用域,就可以进行copy操作,apple提供的接口是Block_Copy()方法,将block复制到heap中。

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
@autoreleasepool {

//Block值捕获
__block  int num = 10;
void(^myBlock)(void) = ^(void){
//我们可以在block内部访问到外部的变量,但是不能修改;
NSLog(@"num = %d",num);

num = 20;//修改外部变量的值;

};

myBlock();

NSLog(@"numnum = %d",num);

}
return 0;
}


输出结果如下:


.

github主页:https://github.com/chenyufeng1991  。欢迎大家访问!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: