我的macOS应用程序存在严重的内存泄漏。经过大量的调试,我似乎已经找到了原因,尽管我仍然不是真的理解它。
应用程序将像素绘制到内部缓冲区,然后在NSView子类的drawRect方法中实际绘制到屏幕。重绘是由[self setNeedsDisplayInRect:rect]触发的。
几个小时后,该程序将消耗数of的RAM。然而,当我把对setNeedsDisplayInRect的调用放在一个循环中来调用它,比如说,当我想重新绘制时,调用它10,000次,而不是只调用一次,内存消耗在几分钟内就会上升到in。
为了确保drawRect方法中的内存不会泄漏,我删除了整个正文,只留下一个空方法。
据我从文档中了解,所有提供给setNeedsDisplayInRect的rects都会被存储,直到事件循环的下一次运行中实际处理了重新绘制。因此,当我调用它10,000次时,我预计内存消耗会更高,但我不会期望它一直在上升-我希望所有存储的rects在一次事件循环迭代后都会被清除。
那么,为什么在调用setNeedsDisplayInRect时,内存量会持续上升呢?我知道每秒调用它10,000次并不是很正常的使用,但在正常情况下内存使用量也在不断增加,尽管速度要慢得多。
代码摘录:
- (void)drawRect:(NSRect)dirtyRect {
// Currently, nothing happening
}
// My own method, that gets called from elsewhere.
- (void) drawToScreen:(int) x : (int) y : (int)w :(int)h :(int *)data
{
int rectYPos = MAX(height - y - h, 0);
NSRect rect = NSMakeRect(x, rectYPos, w, h);
for(int i = 0; i < 10000; i++)
{
[self setNeedsDisplayInRect:rect];
}
}发布于 2017-02-16 23:25:09
如果你从一个辅助/后台线程调用它,你可能需要回顾一下(来自苹果的文档):
“如果应用程序的辅助线程希望在主线程上重绘视图的某些部分,则不能使用display、setNeedsDisplay:、setNeedsDisplayInRect:或setViewsNeedDisplay:等方法执行此操作。相反,它应向主线程发送消息或使用performSelectorOnMainThread:withObject:waitUntilDone:方法调用这些方法。”
https://stackoverflow.com/questions/42270636
复制相似问题