macos - NSImage TIFFRepresentation 未随 ARC 一起发布

标签 macos cocoa memory memory-leaks automatic-ref-counting

我有一个 OSX Cocoa ARC 项目,可以处理数千张图像。为了减少图像数量,我们扫描图像以查看它们是否是统一的颜色,如果是,我们丢弃该图像并跟踪其颜色。

获取纯色的代码是:

- (NSColor *)getSolidColor:(NSImage *)image
{
NSBitmapImageRep* raw_img = [NSBitmapImageRep imageRepWithData:[image TIFFRepresentation]];

int Bpr = [raw_img bytesPerRow],spp = [raw_img samplesPerPixel];
unsigned char *data = [raw_img bitmapData];
int w = [raw_img pixelsWide],h = [raw_img pixelsHigh];

uint32_t mask = 0x00FFFFFF;
uint32_t color = *((uint32_t *)data) & mask;

    for( int y=0; y<h; y++ ) 
    {
    unsigned char *p = data + Bpr*y;

        for( int x=0; x<w; x++ ) 
        {
            if( color != (*((uint32_t *)p) & mask) )
                return( nil );
            p += spp;
        }
    }

    return( [raw_img colorAtX:0 y:0] );
}

(为简洁起见,删除了一些错误检查 - 上面的代码假设每个像素 3 个样本。)

调用它的代码基本上是:

NSString *imageFile;
while( imageFile = [self getNextImageFile] )
{
NSImage *image = [[NSImage alloc] initWithContentsOfFile:imageFile];
    if( [image isValid] && [self getSolidColor:image] )
        [fileManager removeItemAtPath:imageFile error:nil];
}

问题在于应用程序消耗了大量内存。当我在探查器中运行它时,它表明所使用的 90% 的内存是由 [NSImage TIFFRepresentation] (上面粗体显示的)分配的。

即TIFFRepresentation 数据和 NSBitmapImageRep 永远不会被释放,即使它们在函数返回后立即超出范围。

为什么?我应该/可以做什么来强制 ARC 释放这些 block ?

使用非 ARC 的“旧方法”,我只需在图像的 while 循环内放置一个自动释放池,这样就可以解决问题。 ARC有这样的概念吗?

谢谢。

(PS。NSZombies 未启用。)

最佳答案

从概念上讲,自动释放池在 ARC 中仍然可用,只是您不能再使用 NSAutoreleasePool 类。

改用新的@autoreleasepool关键字:

@autoreleasepool {
   //Do stuff that you previously would have wrapped in an NSAutoreleasePool...
}

关于macos - NSImage TIFFRepresentation 未随 ARC 一起发布,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10466563/

相关文章:

java - 为 KeyStroke 设置多个掩码

c - GTK 和 plplot 的例子?

objective-c - NSCollectionView 不显示其内容

cocoa - OpenGL 纹理绑定(bind)失败

macos - 使用 PubSub 获取 Gmail 未读邮件计数

c - 为什么 malloc 使用零大小?

database - 双向多路归并排序

python - pandas to_hdf 函数获取非法指令

MySQL填满内存并卡住

python - 如何分发适用于 Mac OS 的应用程序,以便双击即可运行该应用程序?