iOS的block内存管理

简介:

初始情况下:

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的循环引用的。

欢迎加群互相学习,共同进步。QQ群:iOS: 58099570 | Android: 572064792 | Nodejs:329118122 做人要厚道,转载请注明出处!


















本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sunshine-anycall/p/4780356.html ,如需转载请自行联系原作者

相关文章
|
8月前
|
iOS开发
iOS block修饰符用copy还是strong
iOS block修饰符用copy还是strong
99 0
|
iOS开发 异构计算
如何增加 iOS APP 虚拟地址空间及内存上限?XNU 内核源码解读
1. 引言 最近一段时间在做钉钉 iOS 内存专项治理,解决内存不足时的 jetsam 事件及 malloc 的异常崩溃。在进程创建时系统会为每个 app 设定内存最大使用上限,内核会维护一个内存阈值优先级列表,当设备内存不足时低优先级的 app 会首先被内核中止进程。在阅读 XNU 内核源码过程中我们发现提供系统了两种能力可以扩展 App 的虚拟地址空间(com.apple.developer.kernel.extended-virtual-addressing)和增加内存使用上限(com.apple.developer.kernel.increased-memory-limit)。
1412 0
如何增加 iOS APP 虚拟地址空间及内存上限?XNU 内核源码解读
|
存储 算法 Java
iOS开发 - 穿针引线之内存管理(二)
iOS开发 - 穿针引线之内存管理
192 0
|
存储 程序员 C语言
iOS开发 - 穿针引线之内存管理(一)
iOS开发 - 穿针引线之内存管理
159 0
|
iOS开发 开发者
iOS开发 - 如何写出漂亮的block
iOS开发 - 如何写出漂亮的block
75 0
|
iOS开发
iOS开发- 关于Block的几种应用
iOS开发- 关于Block的几种应用
92 0
|
iOS开发 Python
iOS小技能:lldb打印block参数签名
iOS逆向时经常会遇到参数为block类型,本文介绍一个lldb script,可快速打印出Objective-C方法中block参数的类型。
159 0
iOS小技能:lldb打印block参数签名
|
自然语言处理 iOS开发
IOS——Block
IOS——Block
63 0
|
iOS开发
iOS代理 通知 block传值的规范写法
iOS代理 通知 block传值的规范写法
116 0
|
存储 算法 iOS开发