内存泄漏| NSArray objectEnumerator |?

时间:2012-04-16 05:51:16

标签: objective-c xcode cocoa memory-management

以下主题说明如何查找当前包含鼠标光标的屏幕:

http://www.cocoabuilder.com/archive/cocoa/104529-current-mouse-screen.html

- (NSScreen *)currentScreenForPointUsingEnumeration:(NSPoint)aPoint
{
    NSEnumerator *screenEnumerator = [[NSScreen screens] objectEnumerator];
    NSScreen *screen;
    while ((screen = [screenEnumerator nextObject]) && !NSMouseInRect(aPoint, screen.frame, NO));

    return screen;
}

我在每次移动鼠标时都会运行。

不幸的是,使用Xcode的工具中的“分配”功能,上面的代码显示了NSFastEnumeration的许多分配。

分析仪中没有出现“泄漏”,但分配计数不断增加,永不减少。该应用程序的整体内存使用量也在不断增加。

使用for(...)循环的类似函数没有相同的问题。

我有什么办法可以改善这里的表现吗?或者这是我不应该担心的事情?

编辑:

顺便说一下,尝试[[[NSScreen screens] objectEnumerator] autorelease]会崩溃应用程序并完全锁定我的鼠标。无法单击或以其他方式找出退出应用程序或Xcode的方法。需要重启OS X.所以不要这样做。

3 个答案:

答案 0 :(得分:1)

  

我有什么办法可以改善这里的表现吗?

我不确定您认为存在性能问题的原因。分析仪显示没有泄漏,所以除非它有缺陷(不幸的是,这些天不是不可能),否则可能没有泄漏。

如果将代码包装在自动释放池中,则NSFastEnumerations应该被取消分配。

答案 1 :(得分:0)

你可以尝试两件事;不确定哪个会有所帮助,或者他们是否会提供帮助。

一,使用实际的快速枚举语法:

for( NSScreen * screen in [NSScreen screens] ){
    if( NSMouseInRect(aPoint, screen.frame, NO) ){
        return screen;
    }
}

或者将它包装在您自己的自动释放池中,以帮助创建的数组和枚举器对象尽快解除分配。

NSScreen *screen = nil;
@autoreleasepool{
    NSEnumerator *screenEnumerator = [[NSScreen screens] objectEnumerator];
    while ((screen = [screenEnumerator nextObject]) && !NSMouseInRect(aPoint, screen.frame, NO));
    [screen retain];    // Ensure screen sticks around past return; only under MRR
}
return [screen autorelease];

答案 2 :(得分:0)

您可以尝试使用块,和/或将其包装在自动释放池中,例如:

__block NSScreen *retVal = nil;
[[NSScreen screens] enumerateObjectsWithOptions:NSEnumerationConcurrent 
     usingBlock:^(Screen *scrn, NSUInteger idx, BOOL *stop) {
         if (NSMouseInRect(aPoint, scrn.frame, NO)) {
           retVal = scrn;
           *stop = YES;
     }];
return retVal;