在GarbageCollection下泄漏NSScreen,这是一个bug

时间:2010-11-23 01:30:28

标签: macos garbage-collection core-graphics

过去几天我一直在尝试在一个Objective-c程序中调试内存泄漏,并且正在玩一些非常基本的示例代码来测试一些想法,并且遇到了一些似乎对我来说是个错误的东西但是当想要在Mac世界中进行开发时,想要从那些拥有更多知识的人那里得到一些意见。

我有以下代码:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

NSRect desktopRect = NSZeroRect;

NSArray* screens = [[NSScreen screens] autorelease];
int x = 0;
for (x = 0; x < [screens count]; x++)
{
    NSScreen *screen = [screens objectAtIndex:x];
}   

[pool drain];

此代码位于我从while循环调用的方法中,该循环一直持续到我终止该进程。 (请记住,这只是一个简单的测试。)

当我运行这个循环并观察乐器中的分配时,当我没有实现垃圾收集时,事情完全正常。我的总分配数保持不变,并且NSScreens的所有内容都会被清理和释放。

一旦启用垃圾收集,对[NSScreen屏幕]的调用就会开始泄漏核心图形对象,就像永远不会释放它们一样。

我在其他论坛上看到几年前人们谈到Core Graphics在垃圾收集下非常漏洞。我想知道这是否也是如此。

来自社区的任何想法?

1 个答案:

答案 0 :(得分:1)

好的,我会在这里说出来并说是的,这是苹果部分的一个错误,虽然我确实找到了使用一些Toll-Free-Bridging魔法的解决方案。我将代码修改为:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

NSRect desktopRect = NSZeroRect;

CFArrayRef screens = CFMakeCollectable((CFArrayRef)[NSScreen screens]);
int x = 0;
for (x = 0; x < [screens count]; x++)
{
    NSScreen *screen = (NSScreen*)CFArrayGetValueAtIndex(screens,x);
}   

[pool drain];

通过在免费桥接阵列上调用CFMakeCollectable,它允许在使用垃圾收集时正确清理后台核心图形对象。

这绝对让我觉得Apple需要对包装Core Graphics的垃圾收集和Cocoa对象做更多的工作。