初始情况下:

block本身、__block修饰的变量以及在block内部使用的变量都是在栈里的。

__block修饰的变量的地址会作为实参传入block块内部(暂时先这么理解,实际比较复杂)。block使用的外部变量被const拷贝到了block内部。也就是block使用的外部变量和这个外部变量本身没有关系。

copy方法之后

被拷贝的方法还是在栈上。但是拷贝之后的block已经被放在了heap(堆)上。同时__block修饰的变量被移动到了堆上,原来在栈上的已经不存在。还有block的外部变量的const拷贝也被拷贝到了堆上。

如果block块使用的外部变量是一个refernce的对象,那么这个对象的引用计数会增加1。

堆上的block再做一次copy之后,只是引用计数增加1,但是不会重新再做拷贝动作。

retain操作

由于retain是有返回值的。retain要求返回的地址和调用对象的地址一致。但是block的地址可能是会变的(尤其是从栈到堆的过程),所以对block做retain操作是没有用处的。什么都不会做!

销毁(或内存回收时)

heap上的block块先于stack上的被销毁时,如调用release销毁堆上的block块。heap中的block块在引用计数变为0的时候被销毁。而__block修饰的变量还在heap中,因为stack还要使用,同时栈上的block快也要使用。

当heap上的block块晚于stack时,stack会被清除。在heap中的block块在调用release减少引用计数到0的时候释放内存。

block和Objective-C对象

如果对block做拷贝操作,block会对其内部使用的对象生成强引用。

如果在block块内部使用了:

  1. 以引用的方式使用了类的成员变量,那么这个block会对self产生强引用。
  2. 以值得方式使用了类的成员变量,那么这个block会对这个变量本身产生强引用。

例如:

dispatch_async(queue, ^{
// instanceVariable is used by reference, a strong reference is made to self
doSomethingWithObject(instanceVariable);
}); id localVariable = instanceVariable;
dispatch_async(queue, ^{
/*
localVariable is used by value, a strong reference is made to localVariable
(and not to self).
*/
doSomethingWithObject(localVariable);
});

以上可以通过__block修饰符来改变。是的__block是另外的一种存储类型,就像copy、retain什么的。这样这个引用就直接被传递到了block中。

但是__block是不可以用来消除对self的循环引用的。

iOS的block内存管理的更多相关文章

  1. iOS夯实:内存管理

    iOS夯实:内存管理 文章转自 内存管理 最近的学习计划是将iOS的机制原理好好重新打磨学习一下,总结和加入自己的思考. 有不正确的地方,多多指正. 目录: 基本信息 旧时代的细节 新时代 基本信息 ...

  2. IOS开发的内存管理

    关于IOS开发的内存管理的文章已经很多了,因此系统的知识点就不写了,这里我写点平时工作遇到的疑问以及解答做个总结吧,相信也会有人遇到相同的疑问呢,欢迎学习IOS的朋友请加ios技术交流群:190956 ...

  3. IOS开发小记-内存管理

    关于IOS开发的内存管理的文章已经很多了,因此系统的知识点就不写了,这里我写点平时工作遇到的疑问以及解答做个总结吧,相信也会有人遇到相同的疑问呢,欢迎学习IOS的朋友请加ios技术交流群:190956 ...

  4. [转载]对iOS开发中内存管理的一点总结与理解

    对iOS开发中内存管理的一点总结与理解   做iOS开发也已经有两年的时间,觉得有必要沉下心去整理一些东西了,特别是一些基础的东西,虽然现在有ARC这种东西,但是我一直也没有去用过,个人觉得对内存操作 ...

  5. iOS Block 内存管理的探讨

    在很多情况下Block是造成程序循环引用内存泄漏的元凶.下面我们就讲解一下block对内存管理的影响.在讲解之前.希望大家对block有一定的了解.如果大家还不是太清楚block的实现原理.希望大家可 ...

  6. iOS开发ARC内存管理技术要点

    本文来源于我个人的ARC学习笔记,旨在通过简明扼要的方式总结出iOS开发中ARC(Automatic Reference Counting,自动引用计数)内存管理技术的要点,所以不会涉及全部细节.这篇 ...

  7. iOS开发ARC内存管理

    本文的主要内容: ARC的本质 ARC的开启与关闭 ARC的修饰符 ARC与Block ARC与Toll-Free Bridging ARC的本质 ARC是编译器(时)特性,而不是运行时特性,更不是垃 ...

  8. (转)iOS开发ARC内存管理技术要点

    转自:http://www.cnblogs.com/flyFreeZn/p/4264220.html 本文来源于我个人的ARC学习笔记,旨在通过简明扼要的方式总结出iOS开发中ARC(Automati ...

  9. iOS MRC ARC 内存管理

    转自:http://www.jianshu.com/p/48665652e4e4 1. 什么是内存管理 程序在运行的过程中通常通过以下行为,来增加程序的的内存占用 创建一个OC对象 定义一个变量 调用 ...

随机推荐

  1. Kotlin语言学习笔记(4)

    函数 // 函数定义及调用 fun double(x: Int): Int { return 2*x } val result = double(2) // 调用方法 Sample().foo() / ...

  2. 迷你MVVM框架 avalonjs 学习教程10、样式操作

    一般情况下我们通过设置类名就可以改变元素的样式,但涉及到动画部分,就一定需要设置内联样式了,因此有了ms-css.*ms-css*的用法为ms-css-样式名="样式值", 如ms ...

  3. 启动shell时自动启动tmux

    Bash 对bash用户, 只需要将下面命令添加到自己家目录下的.bashrc, 要注意这句命令需要在alias配置之前.对其它shell的配置也是类似的 ~/.bashrc # If not run ...

  4. MySQL Installation of system tables failed!

    刚开始学习Linux,就遇到了问题. 当在RedHat下安装MySQL时提示如下错误,请高手给点指点,谢谢: rpm -vih  MySQL-server-community-5.0.96-1.rhe ...

  5. js中常用的事件

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  6. Maven(Eclipse版)

    前言: 由于最近工作学习,总是能碰到Maven的源码.虽然平时工作并不使用Maven,但是为了学习一些源码,还是必须要了解下.这篇文章不是一个全面的Maven解析,而是一个简单的介绍,包括Eclips ...

  7. golang获取IP地址

    ip:=this.Ctx.Request.RemoteAddr ip=ip[0:strings.LastIndex(ip, ":")]

  8. C++强制转换

    static_cast,dynamic_cast, const_cast, reinterpret_cast dynamic_cast比static_cast多了安全检测,判断源和目标有无继承被继承关 ...

  9. WebMagic写的网络爬虫

    一.前言 最近因为有爬一些招聘网站的招聘信息的需要,而我之前也只是知道有“网络爬虫”这个神奇的名词,具体是什么.用什么实现.什么原理.如何实现比较好都不清楚,因此最近大致研究了一下,当然,研究的并不是 ...

  10. mysql非主键自增长

    mysql并非只有主键才能自增长,而是设为键的列就可以设置自增长.   如下: CREATE TABLE t1 ( id INT, col1 INT auto_increment NOT NULL ) ...