github.com/C100515C/Bl…

Block简介(copy一段)

Block作为C语言的扩展,并不是高新技术,和其他语言的闭包或lambda表达式是一回事。需要注意的是由于Objective-C在iOS中不支持GC机制,使用Block必须自己管理内存,而内存管理正是使用Block坑最多的地方,错误的内存管理 要么导致return cycle内存泄漏要么内存被提前释放导致crash。 Block的使用很像函数指针,不过与函数最大的不同是:Block可以访问函数以外、词法作用域以内的外部变量的值。换句话说,Block不仅 实现函数的功能,还能携带函数的执行环境。

可以这样理解,Block其实包含两个部分内容

Block执行的代码,这是在编译的时候已经生成好的;

一个包含Block执行时需要的所有外部变量值的数据结构。 Block将使用到的、作用域附近到的变量的值建立一份快照拷贝到栈上。

Block与函数另一个不同是,Block类似ObjC的对象,可以使用自动释放池管理内存(但Block并不完全等同于ObjC对象,后面将详细说明)。

Block的类型与内存管理

根据Block在内存中的位置分为三种类型NSGlobalBlock,NSStackBlock, NSMallocBlock。

NSGlobalBlock:类似函数,位于text段;(一直存在,可以用,只有在运行完才释放)

NSStackBlock:位于栈内存,函数返回后Block将无效;

NSMallocBlock:位于堆内存。(需要使用自动释放或者手动释放)对NSStackBlock 进行copy就是NSMallocBlock

Block的copy、retain、release操作 

NSGlobalBlock:retain、copy、release操作都无效:NSStackBlock:retain、release操作无效,必须注意的是,NSStackBlock在函数返回后,Block内存将被回收。即使retain也没用。容易犯的错误是[[mutableAarry addObject:stackBlock],(补:在arc中不用担心此问题,因为arc中会默认将实例化的block拷贝到堆上)在函数出栈后,从mutableAarry中取到的stackBlock已经被回收,变成了野指针。正确的做法是先将stackBlock copy到堆上,然后加入数组:[mutableAarry addObject:[[stackBlock copy] autorelease]]。支持copy,copy之后生成新的NSMallocBlock类型对象。

NSMallocBlock支持retain、release,虽然retainCount始终是1,但内存管理器中仍然会增加、减少计数。copy之后不会生成新的对象,只是增加了一次引用,类似retain;

结果是 只有局部变量引用计数加一,block copy 是不创建新对象;

__globalObj和__staticObj在内存中的位置是确定的,所以Block copy时不会retain对象。

_instanceObj在Block copy时也没有直接retain _instanceObj对象本身,但会retain self。所以在Block中可以直接读写_instanceObj变量。

localObj在Block copy时,系统自动retain对象,增加其引用计数。

blockObj在Block copy时也不会retain。

循环引用retain cycle

循环引用指两个对象相互强引用了对方,即retain了对方,从而导致谁也释放不了谁的内存泄露问题。如声明一个delegate时一般用assign而不能用retain或strong,因为你一旦那么做了,很大可能引起循环引用。在以往的项目中,我几次用动态内存检查发现了循环引用导致的内存泄露。

这里讲的是block的循环引用问题,因为block在拷贝到堆上的时候,会retain其引用的外部变量,那么如果block中如果引用了他的宿主对象,那很有可能引起循环引用,如:

self.myblock = ^{

[self doSomething];

};

总结:

1.默认情况下, block的内存是在栈中(NSStackBlock

* 它不会对所引用的对象进行任何操作

2.如果对block做一次copy操作, block的内存就会在堆中(NSMallocBlock

* 它会对所引用的对象做一次retain操作

* 非ARC : 如果所引用的对象用了__block修饰, 就不会做retain操作

* ARC : 如果所引用的对象用了__unsafe_unretained\__weak修饰, 就不会做retain操作

3.修改外部引用时, Block变量,被__block修饰的变量称作Block变量。 基本类型的Block变量等效于全局变量、或静态变量,可以在block内部修改,不会拷贝一份。非Block变量,在block内使用不能修改,内部是对外部的拷贝,外部修改也不影响内部的使用。

转载于:https://juejin.im/post/5a6319a351882573392cd40a

block--内存管理相关推荐

  1. iOS的block内存管理

    初始情况下: block本身.__block修饰的变量以及在block内部使用的变量都是在栈里的. __block修饰的变量的地址会作为实参传入block块内部(暂时先这么理解,实际比较复杂).blo ...

  2. iOS之Block总结以及内存管理

    block定义 struct Block_descriptor {unsigned long int reserved;unsigned long int size;void (*copy)(void ...

  3. Block介绍(二)内存管理与其他特性

    为什么80%的码农都做不了架构师?>>>    我们在前一章介绍了block的用法,而正确使用block必须要求正确理解block的内存管理问题. 这一章,我们只陈述结果而不追寻原因 ...

  4. Block 本质、实现原理、内存管理、循环引用、__block等

    一.Block介绍 1.1概念: 将函数及其执行上下文封装起来的对象 底层用struct实现 1.2block实现原理: a .新建项目 代码放入file.m中 b.打开终端cd到项目目录下 c.敲c ...

  5. ORACLE 内存管理 之六 SGA Multiple Block Sizes,Large Pool

    ORACLE DBA 内存管理 SGA Multiple Block Sizes,Large Pool Multiple Block Sizes 9i前只能设置一种blocksize,如果想改变只能重 ...

  6. redis 数据结构 内存管理 持久化

    为什么80%的码农都做不了架构师?>>>    Redis 内存数据结构与编码 OBJECT encoding key.DEBUG OBJECT key 简单动态字符串(simple ...

  7. iOS 进阶—— iOS内存管理

    1 似乎每个人在学习 iOS 过程中都考虑过的问题 alloc retain release delloc 做了什么? autoreleasepool 是怎样实现的? __unsafe_unretai ...

  8. HybridDB · 源码分析 · MemoryContext 内存管理和内存异常分析

    背景 最近排查和解决了几处 HybridDB for PostgreSQL 内存泄漏的BUG.觉得有一定通用性. 这期分享给大家一些实现细节和小技巧. 阿里云上的 HybridDB for Postg ...

  9. Python3.5源码分析-内存管理

    Python3源码分析 本文环境python3.5.2. 参考书籍<<Python源码剖析>> python官网 Python3的内存管理概述 python提供了对内存的垃圾收 ...

  10. 《C++应用程序性能优化::第五章动态内存管理》学习和理解

    <C++应用程序性能优化::第五章动态内存管理>学习和理解 说明:<C++应用程序性能优化> 作者:冯宏华等 2007年版. 2010.8.29 cs_wuyg@126.com ...

最新文章

  1. linux部署vue项目_Vue项目部署的最佳实践
  2. android弹出输入框不影响布局,android 输入法弹出后,不影响activity原有布局
  3. how is navigation list item click event handled - actually no logic done
  4. java+mysql性能优化_Java培训实战教程之mysql优化
  5. 数据分析:复杂业务场景下,量化评估流程
  6. tomcat stdout文件快速增长原因_Tomcat下载安装及配置
  7. java怎么设置窗体title_自定义Java窗口标题栏菜单
  8. 51单片机读引脚和读端口测试总结
  9. ASK、OOK、FSK、GFSK 学习
  10. 关于新闻:西瓜3毛一斤仍滞销 被当垃圾扔掉 问题的一点看法
  11. [源码解析]ESPnet脚本源码解析-aishell-asr.sh
  12. 医院管理系统(Java+SSM+MySQL开发的医院科室管理系统)
  13. 【BIB文献管理】LATEX使用bib
  14. 【华为机试真题 Python】窗口滑动和最大值
  15. 托福 独立写作题型分类与总结
  16. idea必备开发插件.
  17. CSS---按住录音提示框制作
  18. 缓冲、运放、跟随电路详解及区分
  19. 第 3-5 课:Flutter 调试及 Android 和 iOS 打包
  20. Ubuntu开机黑屏且左上角闪烁光标,登录页面键盘鼠标无响应的解决方法

热门文章

  1. MultiResolution研究
  2. kaldi 源码分析(七) - HCLG 分析
  3. 编写第二个页面:新闻阅读列表页面
  4. Centos 7 安装 memcached
  5. Android实现按钮点击效果(第一次点击变色,第二次恢复)
  6. Android屏幕适配和文字屏幕适配
  7. MySQL中处理Null时要注意两大陷阱
  8. Struts2 整合jQuery实现Ajax功能
  9. 后端开发如何设计数据库系列文章(一)设计传统系统表结构(Java开发)
  10. 两图说明 java 开发工具中启动类参数都是干嘛的