我正在处理图像的应用程序。这就像用户最多放置 4 个图像,然后应用程序根据用户选择的模板对它们进行布局。一张图片可能会在最终视图中添加 2-3 次。
布局中的每个图像都是在 NSView 中绘制的(NSView 的 drawRect 方法使用 drawInRect 方法)。现在最终图像(通过布局所有图像的组合图像)是通过将 NSView 保存为 Image 来创建的,并且一切正常。
现在我面临的问题是一旦所有处理完成,内存就会被应用程序保留。我使用了仪器分配,我没有看到内存泄漏,但我看到“持久字节”随着应用程序的每个会话不断增加,并且一个用户报告了 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;
Run Code Online (Sandbox Code Playgroud)
上面的代码我用来在 NSView 的 drawRect 方法中绘制图像,图像中显示的代码用于将 NSView 获取为 Image。
更新:经过我的进一步调查,我发现它的CGImageSourceCreateWithData被缓存NSImage中的TIFF数据。我更多地使用下面的代码来裁剪图像,如果我取消注释它,内存消耗就可以正常工作。
NSData *imgData = [imageToCrop TIFFRepresentation];
CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)imgData, NULL);
CGImageRef maskRef = CGImageSourceCreateImageAtIndex(source, 0, NULL);
CGImageRef …Run Code Online (Sandbox Code Playgroud) 这是我使用的代码:
NSImage *image = [[NSBundle bundleForClass:[self class]] imageForResource:@"test.jpg"];
NSData *originalData = [image TIFFRepresentationUsingCompression:NSTIFFCompressionJPEG factor:1.];
Run Code Online (Sandbox Code Playgroud)
给originalData.length了我 1802224 字节 (1.7MB)。而磁盘上的镜像大小为457KB。为什么TIFFRepresentation会变大以及我应该使用哪种表示形式才能获得原始图像(我想通过网络传输图像)?
我想我在这里缺少一些非常基本的东西.如果我使用我知道存在的合法URL /路径执行此操作:
NSImage* img = [[NSImage alloc] initWithContentsOfFile:[[selectedItem url] path]];
NSLog(@"Image width: %d height: %d", [img size].width, [img size].height);
Run Code Online (Sandbox Code Playgroud)
然后我向控制台报告宽度是-2080177216和高度0.虽然我知道宽度实际上是50和高度50.我尝试调用isValid并返回YES,我也尝试检查大小第一个表示,它返回相同的混乱值.为什么图像加载不正确?
MacOS 10.7.4带有具有144 DPI图像代表的新图标。不好的是,当我在NSImage中加载这些图标之一时,我只会得到512px大小的代表。我的意思是:我在NSImage中加载一个1024px / 144dpi的icns文件,然后询问每个图像代表的大小...没有代表的大小为1024px,我只能得到最大的大小。512像素(无论某个代表的分辨率为72dpi而不是144dpi,实际上:10.7.4中的新图标(例如TextEdit或Automator)对于每种尺寸都有两种分辨率的代表,唯一的代表是1024px(144dpi的单个代表存在该分辨率) )。
难道NSImageRep似乎不了解其真实分辨率?为什么我仅针对1024px / 144dpi而不是例如512px / 144dpi出现此问题?
如果我读取了NSImage的TIFFRepresentation并将其写回到文件中,则会得到正确的1024px / 144dpi TIFF文件,而如果我通过CGImageSource / CGImageDestination编写与kUTTypeTIFF相同的NSImage,则会得到1024px / 72dpi文件。
所有这些使我感到非常困惑。
非常感谢