【ACCESS】行使Xcode和Instruments调节和测试化解iOS内部存款和储蓄器走漏

4、使用Instruments的leaks工具

浅析内部存款和储蓄器败露不能把富有的内部存款和储蓄器败露查出来,有的内部存款和储蓄器走漏是在运营时,用户操作时才发生的。那就需求用到Instruments了。

ACCESS 1 

按上边操作,build成功后跳出Instruments工具,选拔Leaks选项,那时候寿司程序也运行起来了,选中list中的项,拖动等操作后,工具突显效果如下:

ACCESS 2

 

大家莫不都能猜到,海洋蓝的柱子表示内部存储器泄露了。怎么通过那几个工具看到在哪走漏了吗?

先在工具栏按下郎窑红的圈子按钮,把工具监视内部存款和储蓄器的活动停下来。选择Leak,然后点中间十字交叉那,采取Call
Tree.ACCESS 3

 

 

那时左下角的Call
Tree的可选项能够选了。选中Invert Call Tree 和Hide System
Libraries,展现如下:

ACCESS 4

 

那会儿内部存款和储蓄器败露的有血有肉代码找到了,在右侧的中绿框框里钦命了哪个方法出现了内部存款和储蓄器走漏。

你倘诺在那一个格局上双击,就会跳转到具体的代码,哈哈,是或不是很有利。

ACCESS 5

此地应该是提醒百分之百内部存款和储蓄器会走漏。

 

来源:http://blog.csdn.net/totogo2010/article/details/8233565

1、运行Demo。

先下载1个兑现准备好的内部存款和储蓄器败露的Demo吧:leak
app

下载下来,打开运转,程序是1个寿司的列表,列出各类寿司卷。试着选拔中间的几行,应该是选第壹行的时候就完蛋了。崩溃截图:

 

ACCESS 6

在崩溃的地方断住了,知道crash的地点了,然则不亮堂具体crash的案由。

 

6、消除内部存款和储蓄器走漏难题

标题找到了,那就化解吧

有关:tableView:didSelectRowAtIndexPath ,分析下它的内部存款和储蓄器进程:

  1. sushiString变量通过autorelease成立,它的引用计数是1. 
     
  2. 那行代码使得引用计数扩张到2, _lastSushiSelected = [sushiString retain];
  3. 那些方法截止时,sushiString的autorelease生效了,那几个变量的引用计数减弱为1
  4. 当再次实施tableView:didSelectRowAtIndexPath那么些措施时,_lastSushiSelected被赋值了新指针,老的_lastSushiSelected的引用计数照旧1,没有被假释,发生了内存败露。

怎么消除吧?

在_lastSushiSelected =
[sushiString retain];此前把原来的release就ok了:

[cpp] view
plain
copy

  1. [_lastSushiSelected release];  
  2.     _lastSushiSelected = [sushiString retain];  

 

 

2、设置NSZombieEnabled

这是多少个 “EXC_BAD_ACCESS”错误。我们开辟XCode的选项:“NSZombieEnabled”
。在crash时可能会给您更多的部分提醒音信。

安装步骤:1

ACCESS 7

2:勾上粉红框里的

ACCESS 8

运维,按刚才的操作选中个中的cell。再一次crash,此次在output窗口会看到多了一项错误新闻:

 

2012-11-28 13:22:08.911
PropMemFun[2132:11303] *** -[CFString respondsToSelector:]:
message sent to deallocated instance 0x713ebc0

大约意思是:向已出狱的内存发送消息。也等于说使用了已放出的内存,在C语言也正是接纳了“野指针”

ACCESS 9

看了下crash的那一个讲话,sushiString应该是没难题的,它是从stringWithFormat初步化出来的。这正是_lastSushiSelected的问题。

_lastSushiSelected指向了sushiString,sushiString是3个autorelease变量。 在第一回点击时,使用的是sushiString已经被放飞,所以crash了。这为_lastSushiSelected保留一下,就足以用了。代码修改如下:

 

[cpp] view
plain
copy

  1. <span style=”font-size:14px;”>    _lastSushiSelected = [ACCESS,sushiString retain];  
  2. </span>  

运作,这时候不崩溃。

 

虽说iOS
5.0本子之后进入了A奥迪Q3C机制,由于互动引用关系相比较复杂时,内部存款和储蓄器走漏依旧或许存在。所以了然原理很要紧。

此处讲述在没有ALANDC的情景下,怎样利用Instruments来查找程序中的内部存款和储蓄器走漏,以及NSZombieEnabled设置的应用。

正文倘诺你已经相比较熟练Obj-C的内部存款和储蓄器管理机制。

关于:tableView:cellForRowAtIndexPath

本条比较显明,sushiString被alloc和init之后就从未有过自由,能够用stringWithFormat来调用autorelease,代码如下:

 

[cpp] view
plain
copy

  1. NSString *sushiString = [NSString stringWithFormat:@”%d: %@”, indexPath.row, sushiName];  

 

好了,走漏都fix了,再用工具分析看看,那时候你再点,再拖,再怎么操作,都没有内部存款和储蓄器走漏了。声明内部存款和储蓄器走漏被阻止了。

那是本文修复好的app代码:no
LeakApp

 

本文参考:http://www.raywenderlich.com/

 

 

试验的付出条件:XCode
4.5.2

叁 、分析内部存款和储蓄器走漏(shift+command+b)

app不crash了,那看看有没有内部存款和储蓄器走漏。用XCode的Analyze就能分析到何地有内部存款和储蓄器败露

ACCESS 10

浅析现在能够看看:

ACCESS 11

那边提示alertView没被放出,有内存败露,这大家释放

    [alertView release];

再分析,这么些题材一下子就解决了了。

 

相关文章