iOS夯实:ARC时代的内存管理

什么是ARC

Automatic Reference Counting (ARC) is a compiler feature that provides automatic memory management of Objective-C objects. Rather than having to think about retain and release operations [1]

ARC提供是一个编译器的特性,帮助我们在编译的时候自动插入管理引用计数的代码。

最重要的是我们要认识到ARC的本质仍然是通过引用计数来管理内存。因此有时候如果我们操作不当,仍然会有内存泄露的危险。下面就总结一下ARC时代可能出现内存泄露的场景。

内存泄露类型

  1. 循环引用

    基于引用计数的内存管理机制无法绕过的一个问题便是循环引用(retain cycle)

    (Python同样也采用了基于引用计数的内存管理,但是它采用了另外的机制来清除引用循环导致的内存泄露,而OC和Swift需要我们自己来处理这样的问题[^2])

    • 对象之间的循环引用:使用弱引用避免
    • block与对象之间的循环引用:

    会导致Block与对象之间的循环引用的情况有:

    self.myBlock = ^{ self.someProperty = XXX; };

    对于这种Block与Self直接循环引用的情况,编译器会给出提示。

    但是对于有多个对象参与的情况,编译器便无能为力了,因此涉及到block内使用到self的情况,我们需要非常谨慎。(推荐涉及到self的情况,如果自己不是非常清楚对象引用关系,统一使用解决方法处理)

    someObject.someBlock = ^{ self.someProperty = XXX; }; //还没有循环引用
    self.someObjectWithABlock = someObject; // 导致循环引用,且编译器不会提醒

    解决方案:

    __weak SomeObjectClass *weakSelf = self;
    
    SomeBlockType someBlock = ^{
    SomeObjectClass *strongSelf = weakSelf;
    if (strongSelf == nil) {
    // The original self doesn't exist anymore.
    // Ignore, notify or otherwise handle this case.
    }
    [strongSelf someMethod];
    };

    我们还有一种更简便的方法来进行处理,实际原理与上面是一样的,但简化后的指令更易用。

@weakify(self)

[self.context performBlock:^{

// Analog to strongSelf in previous code snippet.

@strongify(self)

// You can just reference self as you normally would. Hurray.
NSError *error;
[self.context save:&error]; // Do something

}];

	你可以在这里找到@weakify,@strongify工具:[MyTools_iOS](https://github.com/100mango/MyTools_iOS)

[^2]: [How does Python deal with retain cycles?](http://www.quora.com/How-does-Python-deal-with-retain-cycles)

2. NSTimer

	一般情况下在action/target模式里 target一般都是被weak引用,除了NSTimer。

	~~~objective-c
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)seconds
target:(id)target
selector:(SEL)aSelector
userInfo:(id)userInfo
repeats:(BOOL)repeats
~~~
在官方文档中:
> target
The object to which to send the message specified by aSelector when the timer fires. The timer maintains a strong reference to this object until it (the timer) is invalidated. Timer Programming Topics :
> A timer maintains a strong reference to its target. This means that as long as a timer remains valid, its target will not be deallocated. As a corollary, this means that it does not make sense for a timer’s target to try to invalidate the timer in its dealloc method—the dealloc method will not be invoked as long as the timer is valid. 举一个例子,一个Timer的Target是ViewController. 这个时候,如果我们是在dealloc方法里让timer invalidate,就会造成内存泄露. 事实上,timer是永远不会被invalidate.因为此时VC的引用计数永远不会为零。因为Timer强引用了VC。而因为VC的引用计数不为零,dealloc永远也不会被执行,所以Timer永远持有了VC. 因此我们需要注意在什么地方invalidate计时器,我们可以在viewWillDisappear里面做这样的工作。

  1. Transitioning to ARC Release Notes ↩︎

【转】iOS夯实:ARC时代的内存管理的更多相关文章

  1. iOS夯实:ARC时代的内存管理

    iOS夯实:ARC时代的内存管理 文章转自 ARC时代的内存管理 什么是ARC Automatic Reference Counting (ARC) is a compiler feature tha ...

  2. ARC时代的内存管理

    什么是ARC Automatic Reference Counting (ARC) is a compiler feature that provides automatic memory manag ...

  3. iOS经典面试题总结--内存管理

    iOS经典面试题总结--内存管理 内存管理 1.什么是ARC? ARC是automatic reference counting自动引用计数,在程序编译时自动加入retain/release.在对象被 ...

  4. ARC下的内存管理

    1.ARC下单对象内存管理 局部变量释放对象随之被释放 int main(int argc, const char * argv[]) { @autoreleasepool { Person *p = ...

  5. iOS学习17之OC内存管理

    1.内存管理的方式 1> iOS应用程序出现Crash(闪退),90%的原因是因为内存问题. 2> 内存问题 野指针异常:访问没有所有权的内存,如果想要安全的访问,必须确保空间还在 内存泄 ...

  6. iOS学习之Object-C语言内存管理

    一.内存管理的方式      1.iOS应用程序出现Crash(闪退),90%的原因是因为内存问题.      2.内存问题:      1)野指针异常:访问没有所有权的内存,如果想要安全的访问,必须 ...

  7. objective-c启用ARC时的内存管理 (循环引用)

    PDF版下载:http://download.csdn.net/detail/cuibo1123/7443125          在Objective-C中,内存的引用计数一直是一个让人比较头疼的问 ...

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

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

  9. objective-c启用ARC时的内存管理

    PDF版下载:http://download.csdn.net/detail/cuibo1123/7443125      在objective-c中,内存的引用计数一直是一个让人比較头疼的问题.尤其 ...

随机推荐

  1. Activity四种启动模式

    转载博客:http://blog.csdn.net/shinay/article/details/7898492 Activity启动方式有四种,分别是:standardsingleTopsingle ...

  2. Android实现对图片的缩放、剪切、旋转、存储

    转载:http://www.cnblogs.com/jerehedu/p/4464870.html 一.问题描述: 在开发中,当我们需要的有一张大图片同时还需要一些小图片时,我们只需要通过代码对此图片 ...

  3. Web前端上万字的知识总结

    下面是自己学HTML+DIV+CSS+JS时的学习笔记,给大家分享以下,相互学习.大二时候寒假在家无聊的时候想做点事,总结了一下web前端基础的东西,下面的每个字都是自己手敲的. 1.<html ...

  4. Ubuntu杂记——双系统重装Win7后找不到Ubuntu的解决办法

    之前装过Ubuntu和Win7的双系统,后来重装了Win7,发现Ubuntu不见了,那会没怎么用,也没去解决问题.现在再看Android内核剖析,大部分都是在Ubuntu环境下进行的,所以百度了一些方 ...

  5. Flume官方文档翻译——Flume 1.7.0 User Guide (unreleased version)中一些知识点

    Flume官方文档翻译--Flume 1.7.0 User Guide (unreleased version)(一) Flume官方文档翻译--Flume 1.7.0 User Guide (unr ...

  6. android防止内存溢出浅析

    Android的虚拟机是基于寄存器的Dalvik,它的最大堆大小一般是16M.但是Android采用的是Java语言编写,所以在很大程度上,Android的内存机制等同于Java的内存机制,在刚开始开 ...

  7. 现代Web应用开发者必备的六大技能

    过去,应用开发需要注重大量的专业知识,程序员只需关注单一的语言(比如COBOL.RPG.C++等),并利用该语言创建应用.而如今,时代在变迁.Web不再是单单关注独立的一面.相反,一个现代化的Web应 ...

  8. jQuery插件之ajaxFileUpload异步上传

    介绍 AjaxFileUpload.js 是一个异步上传文件的jQuery插件,原理是创建隐藏的表单和iframe然后用JS去提交,获得返回值. 下载地址: http://files.cnblogs. ...

  9. QTableWidget详解(样式、右键菜单、表头塌陷、多选等)

    在Qt的开发过程中,时常会用到表单(QTableWidget)这个控件,网上的资料不少,但是都是最基本的,有一些比较经常遇到的问题也说得不太清楚.所以,今天就在这里总结一下! 以下为个人模拟Windo ...

  10. 谈I/O模型

    一个IO操作涉及两个系统对象: 调用这个IO的用户Process/Thread 系统内核 - System Kernel 一个具体的Read操作包括两个阶段: 内核等待数据准备就绪:Waiting f ...