Leaks (instrument) 报告自动释放对象中的泄漏

发布于 2024-09-07 08:02:41 字数 1807 浏览 4 评论 0原文

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

最近,我一直在当前项目上运行 Leaks 来查找泄漏,但我不断遇到这些“泄漏”,据我所知,这些“泄漏”并不是真正的泄漏。根据 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:我尝试将泄漏 1 的行更改为:

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

我认为这消除了泄漏,但最终并没有。所以我还是很茫然。

Update: this leak has been solved. If you are getting similar leaks and your application is multi-threading, you are most likely making UIKit calls from a background thread; make use of e.g. [NSThread performSelectorOnMainThread:] to route UIKit calls out to the main thread, which is the only place where they are allowed.

I've been running Leaks on my current project to find leaks lately, and I keep running into these "leaks" which from what I can tell aren't really leaks. The following code, taken directly from the project, has two leaks, according to 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
}

Leak 1 goes away if I change the first line to: (see Update 2-3)

Leak 2 goes away if I change the last line to:

    return a;

I can't unfortunately do that with leak 1 because I'm casting an immutable array into a mutable one. Still, arrayWithArray is supposed to autorelease, anyway, so from what I can tell, it shouldn't leak anything. Any ideas why this is happening?

Update: I've tested this on both the device and the Simulator. The leak is there on both. However, on the Simulator I get some additional information about this leak:

The history for the leak goes as follows:

# | 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

The things I can discern from the above is that the autoreleased array is somehow retained twice and then autoreleased, leaving retain count at 1. No idea where or why though...

Update 2 & 3: I tried changing the line for Leak 1 to:

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

I thought this removed the leak, but it didn't, ultimately. So I'm still at a loss.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

若言繁花未落 2024-09-14 08:02:41

出乎意料的是,当我用代码解决了一堆其他问题时,这个问题就自行解决了。

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

Anticlimactically, this one solved itself as I solved a bunch of other issues with my code.

Mainly, the code had a number of places where UI updates were made outside of the main thread, which is a big no-no. One of these other unrelated issues must have triggered the memory leak in the above code, since it doesn't report any leaks anymore (I have 0 leaks as it stands), although I haven't modified the code any.

不…忘初心 2024-09-14 08:02:41

retrieveNeighborsForIndex 返回什么?

该方法的结果是否有可能被保留(而不是自动释放)?

What retrieveNeighborsForIndex returns?

Is there a chance that the result of this method is retained (not autoreleased)?

魂归处 2024-09-14 08:02:41

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

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

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

arrayWithArray retains the objects that you stored into your mutable array. http://www.iphonedevsdk.com/forum/iphone-sdk-development/14285-nsmutablearray-arraywitharray-does-add-retain.html

I would recommend releasing it, or safer yet create the objects with the autorelease attribute set. When calling retrive neighbors for index make those objects autorelease and they will be released when the nsmutable array is dealloc'ed

EDIT:
One Tip I might add when tracking down memory bugs is to enable zombies, and check the reference count of your objects. You can then determine which ones are not being released and it should make your tracking easier. This link will show you how to setup your xcode project to enable zombies: cocoadev.com/index.pl?NSZombieEnabled

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文