Objective-C代码块Block详解
2015-10-25 19:41
549 查看
block代码块是OC的一个特性,除了可执行的代码外,还可能包含变量的自动绑定(栈),或内存托管(堆)。所以一个block维护一个状态集(数据),可以在任何时候执行。block用来作为回调特别有用。
block可以作为函数参数或者函数的返回值,而本身又可以带输入参数或返回值。在多线程,异步任务,集合遍历,接口回调等地方用得比较多。使用标识符^.。为了性能,block都是分配在栈stack上面的,它的作用域就是当前函数。
我们来说说block和函数的相似性:
(1)可以保存代码;
(2)有返回值;
(3)有形参;
(4)调用方式一样;
下面我们使用代码来演示一下block的用法:
。
同样,我们可以在声明的时候直接定义block,示例如下:
输出结果如下:
。
block非常重要的一个功能就是进行值捕获。请看一下示例代码:此时我们只能捕获num的值,不能去修改它,因为这是一个值类型,进行的是值传递。
输出结果如下:
。
但是如果因为项目实际需要,需要在block内部修改外部变量的值,那么就可以使用__block关键字修饰变量,示例代码如下:此时的这个变量就变成了引用类型。在block内就可以修改它的值。
但是请注意,只要没对block进行copy操作,block就一直在在stack中,要想延长block的作用域,就可以进行copy操作,apple提供的接口是Block_Copy()方法,将block复制到heap中。
输出结果如下:
.
github主页:https://github.com/chenyufeng1991 。欢迎大家访问!
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 。欢迎大家访问!
相关文章推荐
- Foundation 之 NSArray和NSMutableArray
- error C2248: “CObject::operator =”: 不可访问 private 员(于“CObject”类声明)
- Object C学习笔记2-NSLog 格式化输出数据
- Object方法和异常总结(4)
- Python标准库:内置函数hasattr(object, name)
- js引用类型之Object类型
- Exception starting filter struts2 java.lang.NoClassDefFoundError: org/objectweb/asm/ClassVisitor
- objective-c开发编码规范
- 学习ECMAScript5规范中Object新增的API
- javascript基本语法3 引用类型----Object
- QMetaObject::connectSlotsByName 总结
- Objective-C新特性
- 运行错误:error while loading shared libraries: xxx.so.0:cannot open shared object file: No such file or
- C# JArray与JObject 的使用 json [{}]
- Socket通信readObject()方法出现异常
- JavaScript Object类型 小抄
- sysobjects syscolumns
- Objective-C路成魔【2-Objective-C 规划】
- 我学习Object-C中的收获总结(五)(六)
- 我学习Object-C中的收获总结(三)(四)