【问题标题】:How to stop NSImage lockfocus from Leaking Memory in an NSOperation?如何在 NSOperation 中阻止 NSImage 锁定焦点泄漏内存?
【发布时间】:2011-10-29 07:23:10
【问题描述】:

当我使用锁定/解锁焦点绘制到 NSImage 时,我遇到了内存泄漏的问题。当我注释掉下面的 LEAKS HERE 代码时,泄漏就消失了。所以我知道这就是泄漏发生的地方。

for(int i= 0; i < nNumberImages; ++i)
{
    m_apNSImageArray[i]= [[NSImage alloc] initWithSize:m_viewRect.size];        
    if(!m_apNSImageArray[i])
    {
        return;
    }  

    //LEAKS IN THIS CODE HERE
    [m_apNSImageArray[i] lockFocus];

    //EDIT: Commented the lines below out, but leak persists.    
    //[[[[NSApp delegate] getColors] getAudioWaveColor:YES] setStroke];        
    //[[m_pmaBezierPaths objectAtIndex:i] stroke];    

    [m_apNSImageArray[i] unlockFocus];      
    //TO HERE        
}

我正在使用垃圾回收,这个 for 循环是在 OSX 10.7 Lion 的 NSOperationQueue 中运行的 NSOperation 的一部分。

这是 NSImage 在后台线程/操作上锁定焦点的错误吗?

编辑: 似乎 lockFocus 每次调用时都在分配新空间。

【问题讨论】:

  • 你发布过图片吗?
  • 嗨查克,感谢您的评论。我没有直接释放图像,因为我使用的是垃圾收集 (gc),但在调用上面的代码之前,我确实将 NSImageArray 中的每个元素设置为 nil,它使用 gc 信号收集。
  • 我尝试不在 for 循环中创建新的 NSImage。相反,我只制作了一次,但后来我无法清除 NSImageRep 缓存,并且 lockFocus unlockfocus 代码仍然以相同的速度泄漏。

标签: objective-c memory-leaks osx-lion nsoperation nsimage


【解决方案1】:

我遇到了几乎相同的问题,需要添加一个自动释放池。

非 ARC:

// set up the autorelease pool
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

// do image stuff
NSImage *imagemage = [[NSImage alloc] init];
[maskedImage lockFocus];
[maskedImage unlockFocus];
[image release];

// drain the autorelease pool
[pool drain];

弧:

@autoreleasepool {
    NSImage *imagemage = [[NSImage alloc] init];
    [maskedImage lockFocus];
    [maskedImage unlockFocus];
}

【讨论】:

  • 对于那些在 Swift 中遇到这个问题的人,可能需要不带“@”的 autoreleasepool { } 来消除 NSImage.lockFocus() 出现的“检测到上下文泄漏,CoreAnalytics 返回 false”等消息和 .unlockFocus()。另见swiftrocks.com/autoreleasepool-in-2019-swift
【解决方案2】:

好吧,我仍然不完全确定如何完全阻止泄漏,但我大大减少了锁定/解锁焦点的次数。这基本上解决了我的问题。

【讨论】:

    【解决方案3】:

    我会看看你的 -getColors-getAudioWaveColor: 方法。

    【讨论】:

    • 嗨,Caleb,感谢您的回答。这些方法非常简单,但为了测试它,我只是将 ([[[[NSApp delegate] getColors] getAudioWaveColor:YES] setStroke];) 注释掉了,泄漏仍然以相同的速率持续存在。
    • 如果您使用 Instruments 检测泄漏,您应该能够看到哪些对象正在泄漏。这应该可以为您提供有关它们来自何处的线索。
    • 我使用 Activity Monitor (AM) 来跟踪我的系统内存,但我只是使用 Instruments 的 Leaks 工具尝试查找泄漏,但没有找到任何泄漏。考虑到每次在 AM 中触发对此代码的调用时,我都可以看到内存使用量上升,这很奇怪。
    • 如果 Leaks 工具没有显示内存泄漏,那么您看到的“泄漏”内存可能只是 retain/autoreleased 并等待 gc 获取。
    • 嘿 DarvidsOn,您可能是对的,但需要多长时间才能收集到内存?
    猜你喜欢
    • 1970-01-01
    • 2020-06-14
    • 1970-01-01
    • 2016-01-01
    • 2019-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多