【转】iOS夯实:ARC时代的内存管理
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时代可能出现内存泄露的场景。
内存泄露类型
循环引用
基于引用计数的内存管理机制无法绕过的一个问题便是循环引用(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里面做这样的工作。
【转】iOS夯实:ARC时代的内存管理的更多相关文章
- iOS夯实:ARC时代的内存管理
iOS夯实:ARC时代的内存管理 文章转自 ARC时代的内存管理 什么是ARC Automatic Reference Counting (ARC) is a compiler feature tha ...
- 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中,内存的引用计数一直是一个让人比較头疼的问题.尤其 ...
随机推荐
- OPEN CASCADE Gauss Least Square
OPEN CASCADE Gauss Least Square eryar@163.com Abstract. The least square can be used to solve a set ...
- JSP页面静态化
Ps:好久没写博客了,不是我太懒,是因为苦逼的我出差去上海了,天天加班 刚回成都.... 今天说说jsp页面静态化,知道静态化的朋友都不陌生,说白了就是访问后缀是html 而不是jsp. 没听说过静态 ...
- Rust初步(四):在rust中处理时间
这个看起来是一个很小的问题,我们如果是在.NET里面的话,很简单地可以直接使用System.DateTime.Now获取到当前时间,还可以进行各种不同的计算或者输出.但是这样一个问题,在rust里面, ...
- react+redux教程(三)reduce()、filter()、map()、some()、every()、...展开属性
reduce().filter().map().some().every()....展开属性 这些概念属于es5.es6中的语法,跟react+redux并没有什么联系,我们直接在https:// ...
- ARC内存管理机制详解
ARC在OC里面个人感觉又是一个高大上的牛词,在前面Objective-C中的内存管理部分提到了ARC内存管理机制,ARC是Automatic Reference Counting---自动引用计数. ...
- iOS 利用JSPatch 添加热补丁功能
ios 由于苹果的审核政策,一旦上线后发现bug是件让人崩溃的事情 不过可以利用oc的runtime机制可以家用JSPatch动态的为工程打热补丁 下载地址:https://github.com/ag ...
- 一次发现underscore源码bug的经历以及对学术界『拿来主义』的思考
事情是如何发生的 最近干了件事情,发现了 underscore 源码的一个 bug.这件事本身并没有什么可说的,但是过程值得我们深思,记录如下,各位看官仁者见仁智者见智. 平时有浏览园区首页文章的习惯 ...
- Android PopupWindow怎么合理控制弹出位置(showAtLocation)
说到PopupWindow,应该都会有种熟悉的感觉,使用起来也很简单 // 一个自定义的布局,作为显示的内容 Context context = null; // 真实环境中要赋值 int layou ...
- Django 1.10 中文文档------3.3.8 会话sessions
django支持匿名会话.它将数据存放在服务器端,并抽象cookies的发送和接收过程.cookie包含一个会话ID而不是数据本身(除非你使用的是基于后端的cookie). 3.3.8.1 启用会话 ...
- compilation与编译
关于本配置节的内容不算多,但关于ASP.NET编译的内容还是有一点的,鄙人认为只是了解一下即可,主要影响到部署. 在 App_Code 文件夹中使用多种编程语言 因为 App_Code 文件夹中的源代 ...