Block介绍(二)内存管理与其他特性
我们在前一章介绍了block的用法,而正确使用block必须要求正确理解block的内存管理问题。这一章,我们只陈述结果而不追寻原因,我们将在下一章深入其原因。
一、block放在哪里
我们针对不同情况来讨论block的存放位置:
1.栈和堆
以下情况中的block位于堆中:
void foo()
{
__block int i = ;
int j = ;
void (^blk)(void);
void (^blkInHeap)(void);
blk = ^{ printf("%d, %d\n", i, j);};//blk在栈里
blkInHeap = Block_copy(blk);//blkInHeap在堆里
} - (void)fooBar
{
_oi = ;
OBJ1* oj = self;
void (^oblk)(void) = ^{ printf("%d\n", oj.oi);};
void (^oblkInHeap)(void) = [oblk copy];//oblkInHeap在堆中
}
2.全局区
以下情况中的block位于全局区:
static int(^maxIntBlock)(int, int) = ^(int a, int b){return a>b?a:b;};
- (void)fooBar
{
int(^maxIntBlockCopied)(int, int) =[maxIntBlock copy];
} void foo()
{
int(^maxIntBlockCopied)(int, int) = Block_copy(maxIntBlock);
}
需要注意的是,这里复制过后的block依旧位于全局区,实际上,复制操作是直接返回了原block对象。
二、block引用的变量在哪里
1.全局区
全局区的变量存储位置与block无关:
static int gVar = ;
//__block static int gMVar = 1; void foo()
{
static int stackVar = ;
// __block static int stackMVar = 0;
}
注意,static变量是不允许添加__block标记的
2.堆栈
此时,你可能会问,当函数foo返回后,栈上的j已经回收,那么blkInHeap怎么能继续使用它?这是因为没有__block标记的变量,会被当做实参传入block的底层实现函数中,当block中的代码被执行时,j已经不是原来的j了,所谓物是人非就是这样吧~
另外,如果使用到变量j的所有block都没有被复制至heap,那么这个变量j也不会被复制至heap。
因此,即使将j++这一句放到blk()这句之前,这段代码执行后,控制台打印结果也是:1024, 1。而不是1024, 2
三、其他特性
1.复制的行为
对block调用复制,有以下几种情况:
1.对全局区的block调用copy,会返回原指针,并且这期间不处理任何东西(至少目前的内部实现是这样);
2.对栈上的block调用copy,每次会返回新复制到堆上的block的指针,同时,所有__block变量都会被复制至堆一份(多次拷贝,只会生成一份)。
3.对已经位于heap上的block,再次调用copy,只会增加block的引用计数。
为什么我们不讨论retian的行为?原因是并没有Block_retain()这样的函数,而且objc里面的retain消息发送给block对象后,其内部实现是什么都不做。
2.objc类中的block复制
objc类实例方法中的block如果被复制至heap,那么当前实例会被增加引用计数,当这个block被释放时,此实例会被减少引用计数。
但如果这个block没有使用当前实例的任何成员,那么当前实例不会被增加引用计数。这也是很自然的道理,我既然没有用到这个instance的任何东西,那么我干嘛要retian它?
我们要注意的一点是,我看到网上有很多人说block引起了实例与block之间的循环引用(retain-cycle),并且给出解决方案:不直接使用self而先将self赋值给一个临时变量,然后再使用这个临时变量。但是,大家注意,我们一定要为这个临时变量增加__block标记(多谢第三篇文章回帖网友的提醒)。
Block介绍(二)内存管理与其他特性的更多相关文章
- 全面介绍Windows内存管理机制及C++内存分配实例(四):内存映射文件
本文背景: 在编程中,很多Windows或C++的内存函数不知道有什么区别,更别谈有效使用:根本的原因是,没有清楚的理解操作系统的内存管理机制,本文企图通过简单的总结描述,结合实例来阐明这个机制. 本 ...
- iOS之Block总结以及内存管理
block定义 struct Block_descriptor { unsigned long int reserved; unsigned long int size; void (*copy)(v ...
- Android笔记--Bitmap(二)内存管理
Bitmap(二) 内存管理 1.使用内存缓存保证流畅性 这种使用方式在ListView等这种滚动条的展示方式中使用最为广泛, 使用内存缓存 内存缓存位图可以提供最快的展示.但代价就是占用一定的内存空 ...
- iOS中Block介绍(二)内存管理与其他特性
我们在前一章介绍了block的用法,而正确使用block必须要求正确理解block的内存管理问题.这一章,我们只陈述结果而不追寻原因,我们将在下一章深入其原因. 一.block放在哪里 我们针对不同情 ...
- Block(二)内存管理与其他特性
一.block放在哪里 我们针对不同情况来讨论block的存放位置: 1.栈和堆 以下情况中的block位于堆中: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...
- Block(二)内存管理与其他特性-b
一.block放在哪里 我们针对不同情况来讨论block的存放位置: 1.栈和堆 以下情况中的block位于堆中: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...
- 全面介绍Windows内存管理机制及C++内存分配实例
转自:http://blog.csdn.net/yeming81/article/details/2046193 本文基本上是windows via c/c++上的内容,笔记做得不错.. 本文背景: ...
- Spark(二): 内存管理
Spark 作为一个以擅长内存计算为优势的计算引擎,内存管理方案是其非常重要的模块: Spark的内存可以大体归为两类:execution和storage,前者包括shuffles.joins.sor ...
- JVM介绍&自动内存管理机制
1.介绍JVM(Java Virtual Machine,Java虚拟机) JVM是Java Virtual Machine的缩写,通常成为java虚拟机,作为Java可以进行一次编写,到处执行(Wr ...
随机推荐
- 洛谷1890 gcd区间
题目描述 给定一行n个正整数a[1]..a[n].m次询问,每次询问给定一个区间[L,R],输出a[L]..a[R]的最大公因数. 输入输出格式 输入格式: 第一行两个整数n,m.第二行n个整数表示a ...
- js replace in multi-line string
.replace(/{id}/g, '_' + counter);
- HtmlTestRunner二次封装(TestRunner.py)
将HtmlTestRunner进行二次封装,使报告生成的更方便 import HTMLTestRunner import unittest import time, os class TestRunn ...
- Oracle删除所有表
Oracle 清理用户所有的表 PLSQL中执行语句 select 'drop '||object_type||' '||object_name||';' from user_objects; 结果集 ...
- 正则表达式的秘籍-b
一. 正则表达式和其他方法的比较 1.我们一般将谓词和正则表达式配合使用,这是最常用的方法. - (BOOL)validateNumber:(NSString *) textString { ...
- bp神经网络算法
对于BP神经网络算法,由于之前一直没有应用到项目中,今日偶然之时 进行了学习, 这个算法的基本思路是这样的:不断地迭代优化网络权值,使得输入与输出之间的映射关系与所期望的映射关系一致,利用梯度下降的方 ...
- ExtJS4.2学习(19)在线编辑器Ext.form.HtmlEditor(转)
鸣谢:http://www.shuyangyang.com.cn/jishuliangongfang/qianduanjishu/2013-12-24/191.html --------------- ...
- 关于table的一些兼容性问题
不多说,先来看两个常用的简单效果 ---- 兼容拼比一(普通边线效果) 图一:谷歌.火狐.ie8+下 图二:ie6/7下 从图中看出,ie6/7其实是不认识tr边框线的,,所以平时做项目时候,我们一般 ...
- QT 的信号与槽机制介绍
https://www.ibm.com/developerworks/cn/linux/guitoolkit/qt/signal-slot/ http://www.kuqin.com/qtdocume ...
- Android USB Host 通信程序
换到了一家新公司,于是就有了新的项目.这次的项目 要用Android SDK与USB HID设备进行通信.第一次接触Android SDK,以及USB,记录下源程序.开发过程以及一些心得. 首先,要感 ...