iOS夯实:ARC时代的内存管理
iOS夯实:ARC时代的内存管理
文章转自 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]
[^1]: Transitioning to ARC Release Notes
ARC提供是一个编译器的特性,帮助我们在编译的时候自动插入管理引用计数的代码。
最重要的是我们要认识到ARC的本质仍然是通过引用计数来管理内存。因此有时候如果我们操作不当,仍然会有内存泄露的危险。下面就总结一下ARC时代可能出现内存泄露的场景。
内存泄露类型
循环引用
基于引用计数的内存管理机制无法绕过的一个问题便是循环引用(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
[^2]: How does Python deal with retain cycles?
NSTimer
一般情况下在action/target模式里 target一般都是被weak引用,除了NSTimer。
+ (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里面做这样的工作。
iOS夯实:ARC时代的内存管理的更多相关文章
- 【转】iOS夯实:ARC时代的内存管理
iOS夯实:ARC时代的内存管理 什么是ARC Automatic Reference Counting (ARC) is a compiler feature that provides autom ...
- ARC时代的内存管理
什么是ARC Automatic Reference Counting (ARC) is a compiler feature that provides automatic memory manag ...
- iOS经典面试题总结--内存管理
iOS经典面试题总结--内存管理 内存管理 1.什么是ARC? ARC是automatic reference counting自动引用计数,在程序编译时自动加入retain/release.在对象被 ...
- ARC下的内存管理
1.ARC下单对象内存管理 局部变量释放对象随之被释放 int main(int argc, const char * argv[]) { @autoreleasepool { Person *p = ...
- iOS学习17之OC内存管理
1.内存管理的方式 1> iOS应用程序出现Crash(闪退),90%的原因是因为内存问题. 2> 内存问题 野指针异常:访问没有所有权的内存,如果想要安全的访问,必须确保空间还在 内存泄 ...
- iOS学习之Object-C语言内存管理
一.内存管理的方式 1.iOS应用程序出现Crash(闪退),90%的原因是因为内存问题. 2.内存问题: 1)野指针异常:访问没有所有权的内存,如果想要安全的访问,必须 ...
- objective-c启用ARC时的内存管理 (循环引用)
PDF版下载:http://download.csdn.net/detail/cuibo1123/7443125 在Objective-C中,内存的引用计数一直是一个让人比较头疼的问 ...
- iOS之Block总结以及内存管理
block定义 struct Block_descriptor { unsigned long int reserved; unsigned long int size; void (*copy)(v ...
- objective-c启用ARC时的内存管理
PDF版下载:http://download.csdn.net/detail/cuibo1123/7443125 在objective-c中,内存的引用计数一直是一个让人比較头疼的问题.尤其 ...
随机推荐
- Android 查看内存
文章参照自:http://stackoverflow.com/questions/2298208/how-to-discover-memory-usage-of-my-application-in-a ...
- iOS_城市定位
技术点-利用CoreLoaction框架,实现城市定位功能. 原理: 利用苹果官方提供的CoreLocation框架实现城市定位的功能: 该框架主要包括两个比较有用的类:定位类CLLocationMa ...
- iOS OC语言: Block底层实现原理 (转载)
作者:Liwjing 地址:http://www.jianshu.com/users/8df89a9d8380/latest_articles 先来简单介绍一下Block Block是什么? 苹果推荐 ...
- mysql 索引建立
如何建立mysql索引? 创建索引原则 1.左前缀原则 : mysql索引匹配会从右匹配,到遇到( > < between like)终止.如 我们建立索引(a,b,c,d), a = ...
- 关于java.util.Properties读取中文乱码的正确解决方案(不要再用native2ascii.exe了)
从Spring框架流行后,几乎根本不用自己写解析配置文件的代码了,但近日一个基础项目(实在是太基础,不能用硕大繁琐的Spring), 碰到了用java.util.Properties读取中文内容(UT ...
- 修改LiteIDE 编辑窗口的主题
用习惯了Visual Studio 再看其他编译器总是有点别扭,当然LiteIDE 也是能够自定义主题的,再次感叹作者的用心. 依次: 查看 -> 选项 -> LiteEditor 在编辑 ...
- 提高你的Java代码质量吧:如果有必要,使用变长数组吧
一.分析 Java中的数组是定长的,一旦经过初始化声明就不可改变长度,这在实际使用中非常不方便. 二.场景 比如要对班级学生的信息进行统计,因为我们不知道一个班级会有多少学生(随时都有可能会有学生 ...
- [Practical Git] Show who changed a line last with git blame
When working on a file, we often want to know who made certain changes last; we can use git blame to ...
- android120 zhihuibeijing 开机页面
软件启动旋转动画: 布局: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" ...
- 文件I/O(不带缓冲)之原子操作
一.添写至一个文件 考虑一个进程,它要将数据添加到一个文件尾端.早期的UNIX系统并不支持open的O_APPEND选项,所以程序被编写成下列形式: ) < ) /* position to E ...