drawInRect保留NSImage直到将来的某个点?

时间:2014-01-21 23:11:59

标签: macos cocoa automatic-ref-counting nsimage drawinrect

所以我在NSThread中运行了一些代码,它们在一个循环中创建了一大堆NSImage个。每个图像的一小部分被绘制到另一个NSImage中,然后线程退出。

所以,像

NSImage *outputImage = [[NSImage alloc] initWithSize:size];
[outputImage lockFocus];
while(1000 times)
    NSImage* image = [[NSImage alloc] initWithSize:size];
    ... image is processed ...
    [image drawInRect: ... fromRect: ... ]
[outputImage unlockFocus];

一旦完成,线程使用performSelectorOnMainThread将创建的NSImage发送回主线程,将其放置在视图中。

这一切都很好,最终的图像完全符合我的预期。但是,在循环期间,应用程序的内存使用量呈线性增长 - 好像每个NSImage直到稍后才释放。我的理论是drawInRect调用在某处被流水线化,直到稍后才真正执行。它是否正确?如果是这样,我该如何预防呢?如果我现在使我的循环计数器太大,我的应用程序将崩溃,我想避免这种情况。

我已经尝试将焦点的锁定和解锁移动到循环中,但这没有任何区别。

我已经确认,如果我只取出drawInRect调用,则线程生命周期内的内存使用率会(或多或少)持平。只有在我打电话的时候,记忆才会上升。

我(显然是?)在这个项目中使用ARC,它在OSX10.9中运行。

1 个答案:

答案 0 :(得分:2)

听起来你的NSImages在某些时候被添加到自动释放池中。在游泳池耗尽之前,通常不会冲洗它们。

在这样的情况下,你想制作自己的自动释放池:

NSImage *outputImage = [[NSImage alloc] initWithSize:size];
[outputImage lockFocus];
while(1000 times) {
    @autoreleasepool {
        NSImage* image = [[NSImage alloc] initWithSize:size];
        ... image is processed ...
        [image drawInRect: ... fromRect: ... ]
    }
}
[outputImage unlockFocus];

这会创建一个子池,每次传递都会消耗掉,所以你不会有大量的图像。