一、ARC相对MRC来说,减轻了程序员的大部分内存管理工作,使用ARC的时候也需要十分清除内存管理的原理,不然可能带来一些很难调试的问题。下面是ARC下面需要注意的一些问题

  1)对象互相引用,形成引用循环。引用循环是基于引用计数无法避免的问题,因为Objetive-C实质上还是一种编译时期的内存管理技术,没有引入GC,所以引用循环问题还是需要程序员手工处理。

    具体的处理办法就是使用weak,assign,_unsafe_unretained 修饰变量,打破引用循环。

    对象引用循环可能导致的问题,对象持久不释放,比如内存中存在两个VC,收到通知时,同一个方法执行两次等诡异的现象(大部分人通知的移除放在dealloc里面,放在viewWillAppear中可以避免此问题,但也可能引入更多问题)。

  2)使用ARC的时候,小心处理assign修饰的对象,assign只是简单的赋值,不对对象的引用计数做改变,对象释放了,这个assign记录的对象地址还是不变。向这个对象发送消息的时候,会偶先Crash。

    如果这个对象释放之后,对象内存区域数据,还是没有变化,是不会crash的。

    这一类crash是偶先的,有可能crash极难重现,想要暴漏这些问题,尽量不要使用assign、_unsafe_unretained ,而使用weak。

    有时候assign、_unsafe_unretained是无法避免的,例如NSNotification的observer,KVO的observer,NSValue valueWithNonretainedObject;

    还有可能是因为历史遗留代码中使用到assign、_unsafe_unretained。

  3)多线程传递autoRelease对象可能引起Crash

    autorelease的对象使用一种延迟释放的技术,将对象暂时记录下来,当autorelease pool drain的时候,向对象发送release消息。

    autorelease跟runloop存在一定的联系,runloop的每一次循环中,会默认创建一个autoreleasepool,因此如果在一个线程中,没有创建runloop并且没有创建autoreleasepool,autorelease对象可能存在泄漏。

    跨线程传递一个autorelease对象的时候,有可能对象在原来的线程中被提前释放掉。

    例如下面的代码:

    由于参数没有retain,有可能autorelease参数会被提前释放

- (id) method

{

     NSInvocation *invocation = [nsinvocation alloc] initWith ...
//参数是autorelease的
[invocation setArg:&[nsdata data] atIndex:index]
//延迟调用
invocation performselector:@selector(invoke) afterdelay: }

    这里还有一个ARC下面的例子:

  

23down voteaccepted

I am guessing you are using ARC?

The problem is with the line [invocation getReturnValue:&resultSet];getReturnValue: just copies the bytes of the return value into the given memory buffer, regardless of type. It doesn't know or care about memory management if the return type is a retainable object pointer type. Since resultSet is a __strong variable of object pointer type, ARC assumes that any value that has been put into the variable has been retained, and thus will release it when it goes out of scope. That is not true in this case, so it crashes. (Also, the array that you had resultSet originally point to will be leaked, since getReturnValue: overwrites that value without releasing it. Why you even made that variable point to an object in the first place is beyond me.)

The solution is that you must give a pointer to a non-retained type to getReturnValue:. Either:

NSArray * __unsafe_unretained tempResultSet;
[invocation getReturnValue:&tempResultSet];
NSArray *resultSet = tempResultSet;

or:

void *tempResultSet;
[invocation getReturnValue:&tempResultSet];
NSArray *resultSet = (__bridge NSArray *)tempResultSet;

http://stackoverflow.com/questions/22018272/nsinvocation-returns-value-but-makes-app-crash-with-exc-bad-access

二、MRC 自动转换为ARC是否会引起Crash

  有可能存在这样的情况,请见博客 《ARC下面的对象被释放的bug》

 

  

  

ARC 下面可能导致的内存问题的更多相关文章

  1. ARC下需要注意的内存管理

    ARC下需要注意的内存管理 2016/04/03 · iOS开发 · 内存管理 分享到:1 原文出处: 一不(@luoyibu)    之前发了一篇关于图片加载优化的文章,还是引起很多人关注的,不过也 ...

  2. iOS - Block产生Memory Leaks循环引用导致的内存泄漏以及解决方案

    在ARC(自动引用技术)前,Objective-c都是手动来分配释放 释放 计数内存,其过程非常复杂. ARC技术推出后,貌似世界和平了很多,但是其实ARC并不等同于Java或者C#中的垃圾回收,AR ...

  3. iOS- 再谈ARC里内存问题,ARC里数组、对象内存得不到释放?

    1.前言      本来以为在改成ARC以后,不再需要考虑内存问题了,可是在实践中还是发现有一些内存问题需要注意,今天我不谈block的循环引用的问题,主要说说一些对象.数组不内存得不到释放的情况. ...

  4. 解决MWPhotoBrowser中的SDWebImage加载大图导致的内存警告问题

    下面两种现象,用同一种方法解决 1.解决MWPhotoBrowser中的SDWebImage加载大图导致的内存警告问题 2.突然有一天首页访问图片很慢,至少隔20多秒所有图片才会出来.(解析:app使 ...

  5. SQL Server 内存泄露(memory leak)——游标导致的内存问题

    原文:SQL Server 内存泄露(memory leak)--游标导致的内存问题 转自:http://blogs.msdn.com/b/apgcdsd/archive/2011/07/01/sql ...

  6. 使用block的时候,导致的内存泄漏

    明确,只要在block里边用到我们自己的东西,成员变量,self之类的,我们都需要将其拿出来,把它做成弱指针以便之后进行释放. 在ZPShareViewController这个控制器中,由如下代码: ...

  7. 精华阅读第 13 期 |常见的八种导致 APP 内存泄漏的问题

    本期是移动开发精英俱乐部的第13期文章,都是以技术为主,所以这里就不过多的进行赘述了,我们直接看干货内容吧!本文系ITOM管理平台OneAPM整理. 实际项目中的MVVM(积木)模式–序章 导读:开篇 ...

  8. 在Activity中使用Thread导致的内存泄漏

    https://github.com/bboyfeiyu/android-tech-frontier/tree/master/issue-7/%E5%9C%A8Activity%E4%B8%AD%E4 ...

  9. Android引导页过多导致OOM内存泄漏

    摘要:前几天推广我们APP的时候,有些手机加载引导页的时候会闪退或崩溃,在Bugly显示是OOM异常.    然后Bugly上面显示的解决方案是: 该异常表示未能成功分配字节内存,通常是因为内存不足导 ...

随机推荐

  1. JavaEE XML DOM创建

    DOM创建XML @author ixenos 1.思路: 先封装构建一颗DOM树,然后将DOM树转换成XML文件 2.三种写DOM树到XML文件的方式: 1)使用DOM(或DOM4J.JDOM) 2 ...

  2. mysql权限设置

    想要设定权限,必须通过root用户登录: >> grant all privileges on *.* to root@"%" identified by " ...

  3. FZU 2088 最长队名

    Problem 2088 最长队名  Problem Description Jack所在的班级决定组团报名参加FZU校赛.为了体现班级的团结和睦,班长决定用班级所有人的名字连起来组成一个史上最长最醒 ...

  4. hadoop(二)

    三 Hive和Hbase #安装配置Hbase环境#主要参考https://my.oschina.net/zc741520/blog/388718网站配置的是集群,这里是伪分布,将网站中涉及多个主机的 ...

  5. CentOS6.5部署L2TP over IPSec

    一.环境介绍: 1.CentOS 6.5 (要求双网卡做软路由,如果只是做VPN可以单网卡) a.外网IP: b.内网IP: 2.Window 10 主机一台做为一台内网测试软路由使用: a.内网IP ...

  6. IOS开发调整UILabel的行间距

    CGFloat heih = 20;   NSString * cLabelString = @"这是测试UILabel行间距的text.这是测试UILabel行间距的text.n 这是测试 ...

  7. java操作mongodb——更新数据

    Java中可以通过updateOne,updateMany,replaceOne方法进行集合的文档更新.但是 _id 是不能更新的 updateOne只会更新一条数据,即使通过Filters.lt(& ...

  8. Android对px和dip进行尺寸转换的方法

    px  转换为 dip /** * PX 转换为 DP * * @param context * @param px * @return */ public static int px2dp(Cont ...

  9. Anton and Tree

    Anton and Tree 题目链接:http://codeforces.com/contest/734/problem/E DFS/BFS 每一次操作都可以使连通的结点变色,所以可以将连通的点缩成 ...

  10. Ubuntu 14.04 绑定固定 IP

    参考百度经验首先用root用户登录,然后输入你的root密码,如果不用root登录可以在命令之前添加sudo:然后编辑interfaces 文件,该文件位于/etc/network/下面, 执行如下命 ...