泄漏(仪器)报告自动释放对象中的泄漏

时间:2010-06-28 18:33:13

标签: iphone xcode ipad instruments memory-leaks

更新:此泄漏已经解决。如果您遇到类似的泄漏,并且您的应用程序是多线程的,那么您最有可能从后台线程进行UIKit调用;利用例如[NSThread performSelectorOnMainThread:]将UIKit呼叫路由到主线程,这是 唯一可以允许的地方

我最近在我目前的项目中运行泄漏以发现泄漏,并且我一直在遇到这些“泄漏”,据我所知,这些泄漏并非真正泄漏。根据Leaks的说法,以下代码直接来自项目,有两个漏洞:

- (NSArray *)areaForIndex:(int)index 
{
    NSMutableArray *a = [NSMutableArray arrayWithArray:
        [world  retrieveNeighborsForIndex:index]]; // leak 1
    [a insertObject:[references objectAtIndex:index] atIndex:0];
    return [NSArray arrayWithArray:a]; // leak 2
}

如果我将第一行更改为:,则泄漏1消失(参见更新2-3)

如果我将最后一行更改为:

,则泄漏2消失
    return a;

我不能不幸地使用泄漏1,因为我正在将一个不可变数组转换为可变数组。不过,无论如何,arrayWithArray应该是自动释放的,所以从我所知道的,它不应泄漏任何东西。任何想法为什么会发生这种情况?

更新:我在设备和模拟器上都测试了这个。两者都有泄漏。但是,在模拟器上,我得到了一些关于此泄漏的其他信息:

泄漏的历史如下:

# | Category | Event Type  | Timestamp | RefCt |  Address  | Size | Responsible Library | Responsible Caller
--+----------+-------------+
0 | CFArray  | Malloc      | 00:09.598 |     1 | 0x474f6d0 |   48 | asynchro            | -[muddyGrid areaForIndex:]
1 | CFArray  | Autorelease | 00:09.598 |       | 0x474f6d0 |    0 | Foundation          | NSRecordAllocationEvent
2 | CFArray  | CFRetain    | 00:09.598 |     2 | 0x474f7d0 |    0 | Foundation          | -[NSCFArray retain]
3 | CFArray  | CFRelease   | 00:09.611 |     1 | 0x474f7d0 |    0 | Foundation          | NSPopAutoreleasePool

我从上面可以看出的事情是,自动释放的数组以某种方式保留两次然后自动释放,保留计数为1.不知道在哪里或为什么......

更新2& 3:我尝试将Leak 1的行更改为:

    NSMutableArray *a = [[[NSMutableArray alloc] initWithArray:
        [world retrieveNeighborsForIndex:index]] autorelease];

我认为这样可以消除泄漏,但最终没有。所以我还是不知所措。

3 个答案:

答案 0 :(得分:2)

通过猜测,这个问题解决了,因为我用我的代码解决了许多其他问题。

主要是,代码有很多地方在主线程之外进行UI更新,这是一个很大的禁忌。其中一个其他不相关的问题必须触发上述代码中的内存泄漏,因为它不再报告任何泄漏(我现在有0个泄漏),尽管我没有修改任何代码。

答案 1 :(得分:0)

retrieveNeighborsForIndex会返回什么?

是否有可能保留此方法的结果(未自动释放)?

答案 2 :(得分:-1)

arrayWithArray保留存储在可变数组中的对象。 http://www.iphonedevsdk.com/forum/iphone-sdk-development/14285-nsmutablearray-arraywitharray-does-add-retain.html

我建议发布它,或者更安全但是创建具有autorelease属性集的对象。当为索引调用retrive邻居时,使这些对象自动释放,并且当nsmutable数组被释放时它们将被释放

编辑: 我可能在追踪内存错误时添加的一个提示是启用僵尸,并检查对象的引用计数。然后,您可以确定哪些未发布,并且应该使您的跟踪更容易。此链接将向您展示如何设置您的xcode项目以启用僵尸:cocoadev.com/index.pl?NSZombieEnabled