objective-c – 保留NSImage drawInRect和NSView cacheDisplayInRect内存

objective-c – 保留NSImage drawInRect和NSView cacheDisplayInRect内存,第1张

概述我正在处理的应用程序处理图像.这就像用户下降最多4张图片和应用程序根据用户选择的模板布局它们.最终视图中可能会添加2-3张图像. 布局中的每个图像都是在NSView(使用drawInRect方法的NSView的drawRect方法)中绘制的.现在,通过将NSView保存为图像来创建最终图像(通过布局所有图像组合图像),并且一切都运行良好. 现在我遇到的问题是,所有处理完成后,应用程序将保留内存.我 我正在处理的应用程序处理图像.这就像用户下降最多4张图片和应用程序根据用户选择的模板布局它们.最终视图中可能会添加2-3张图像.

布局中的每个图像都是在NSVIEw(使用drawInRect方法的NSVIEw的drawRect方法)中绘制的.现在,通过将NSVIEw保存为图像来创建最终图像(通过布局所有图像组合图像),并且一切都运行良好.

现在我遇到的问题是,所有处理完成后,应用程序将保留内存.我已经使用了仪器分配,我没有看到内存泄漏,但我看到“持久字节”随着应用程序的每个会话和GB中的一个用户报告问题而不断增加.请看截图.

当我在Instruments中进一步调查时,我看到了导致内存保留的应用程序的代码捕捉.所有这些都与ImageIO和coreImages有关.从仪器见下文:

然而,这似乎只是10.10及以上系统的问题.在10.9.x中测试了相同版本的应用程序,内存使用率保持在60MB.在应用程序中执行会话期间,它会达到200MB,但一旦完成它就会恢复到通常用于应用程序类型的50-60MB.

[_photoImage drawInRect: self.bounds fromrect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0 respectFlipped: YES hints: nil];            _photoImage = nil;

上面的代码我用来在NSVIEw的drawRect方法中绘制图像,图像中显示的代码用于将NSVIEw作为Image.

更新:在我进一步调查后,我发现它是CGImageSourceCreateWithData缓存NSImage的TIFF数据.更多的是我使用下面的代码来裁剪图像,如果我取消注释它的内存消耗只是工作正常.

NSData *imgData = [imagetoCrop TIFFRepresentation];CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)imgData,NulL);CGImageRef maskRef =  CGImageSourceCreateImageAtIndex(source,NulL);CGImageRef imageRef = CGImageCreateWithImageInRect(maskRef,rect);NSImage *cropped = [[NSImage alloc] initWithCGImage: imageRef size:rect.size];CGImageRelease(maskRef);CGImageRelease(imageRef);CFRelease(source);//CFRelease( options );imgData = nil;

我还尝试将kCGImageSourceShouldCache显式设置为false(但默认情况下为false)但结果相同.
请帮助解决内存保留问题.

解决方法 最后经过大量调试后发现CGImageSourceCreateWithData保留了NSImage的TIFF数据.当我更改此行时:

CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)imgData,NulL);

CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)[NSURL fileURLWithPath:path],NulL);

一切都刚刚开始正常工作,应用程序的内存使用量从300MB(6images)降至50-60MB,现在它的行为一致.

除了上面的更改,它仍然会导致内存保留在某处,所以要摆脱它,在完成所有处理后,我清除每个图层的图像为’nil’,这就像魅力一样.我的印象是,将父母视为’nil’也会释放图像,但这不起作用.

无论如何,如果有任何人似乎与drawInRect或cachedisplayInRect有关,那么请确保在以后不需要时清除图像.

2016年7月2日更新

我发现kCGImageSourceShouldCache默认为32位,对于64位为true.通过将其设置为false,我能够使用以下代码释放内存.

const voID *keys[] =   { kCGImageSourceShouldCache};    const voID *values[] = { kcfBooleanFalse};    CFDictionaryRef optionsDictionary = CFDictionaryCreate(NulL,keys,values,1,NulL,NulL);    CGImageSourceRef source = CGImageSourceCreateWithData((__brIDge CFDataRef)[image TIFFRepresentation],optionsDictionary);

希望它可以帮助某人.

总结

以上是内存溢出为你收集整理的objective-c – 保留NSImage drawInRect和NSView cacheDisplayInRect内存全部内容,希望文章能够帮你解决objective-c – 保留NSImage drawInRect和NSView cacheDisplayInRect内存所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1072273.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存