Object-c block块
2016-03-09 15:02
453 查看
block块
块对象(block Object)是在Mac OS X10.6和iOS 4.0平台下可以使用的功能,它不是Object-c而是C语言的功能的实现。Apple的文档中将其称为块对象或Block(复数为Blocks),在其他编程语言中,它与闭包(closure)功能基本相同。
块对象的定义
^(参数列){主体}
这里从“^”开始到参数列,主体最后的大括号,这一段记述称为块对象的块句法(block literal)。实际上,块句法并不是被用于在内存中分配的块对象,它只是编写代码时的一种表达用语。
块对象的实例和生命周期
下面是我看到的一个很有趣的例子
#include <stdio.h> #include <Block.h> void pr(int (^block)(void)) { printf("%d\n",block()); } int (^g)(void)=^{return 100;}; void func1(int n) { int (^b1)(void)=^{return n;}; pr(b1); g=b1; } void func2(int n) { int a=10; int (^b2)(void)=^{return n*a;}; pr(b2); } int main(int argc, const char * argv[]) { pr(g); func1(5); func2(5); pr(g); return 0; }
这是输出的结果
很明显发现最后的pr(g)输出的结果不对
这是因为在func1中将变量b1的块赋值给了外部变量g。但是变量b1中保存的是指向栈的指针。函数func1执行完之后,该块的生命周期也随之结束。由于函数func2的调用会使得栈上被写入其他信息,因此在执行的时候最后pr(g)出错了。
如何修改
将func1中的g=b1;修改为g=Block_copy(b1);,当然要加上头文件 Block.h
Block_copy(block):参数为栈上的块对象,返回堆上复制的块对象。否则(参数为静态数据区或未堆上的块对象)则不进行复制而直接将参数返回,但会增加参数的块对象的引用次数
与之对应的有
Block_release(blcok):减少参数的块的引用计数,减到0时释放块对象的内存区域
对块句法生命周期的总结
- 块句法写在函数外面时,只在静态数据区分配一片内存区域给块对象。这片区域在程序执行期会一直存在。
- 块句法写在函数内时,和自动变量一样,块对象的内存区域会在执行包含块对象的函数时被保存在栈上。该区域的声明周期就是在函数运行期间。
相关文章推荐
- block中“__block typeof(self)bself = self;”的意义
- JSON用法及json对象(Object)和字符串(String)互转
- Object-c动态特性
- block使用技巧
- 《从零开始学Swift》学习笔记(Day 70)——Swift与Objective-C混合编程之Swift与Objective-CAPI映射
- 《从零开始学Swift》学习笔记(Day 69)——Swift与Objective-C混合编程之语言
- Objective-C之block详细介绍
- Objective-C代码,最终会被转换为机器代码 —— 由ARM处理器能识别的1和0组成
- [Objective-C]关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- object_id
- Object-C 中各数据类型转换 NSData转NSString,Byte,UIImage
- GitHub 上排名前 100 的 Objective-C 项目简介
- 为什么客户端解析Json数据的时候没办法得到JSONObject
- ObjectAnimator
- ateObjectsUsingBlock 、for 、for(... in ...) 的区别 & 性能测试 for VS for(... in ...)
- scrollview滚动图片切换
- Objective-C Block基本用法
- 使用objc_getAssociatedObject, objc_setAssociatedObject动态扩展属性
- iOS 开发--Objective-C 反射机制
- object references an unsaved transient instance - save the transient instance before flushing