2

我一直在使用

NSMutableData* mutableData = [NSMutableData dataWithLength: someLength];
void* bitmapData = [mutableData mutableBytes];
CGContextRef context = CGBitmapContextCreate(bitmapData,...);
// ...use context
CGContextRelease(context);

我有一个自动释放池,但是在 Instruments 中查看它时,mutableData似乎没有被释放。
我想过使用alloc/init如下所示,但我不确定发送release是否也会清除bitmapData

NSMutableData* mutableData = [[NSMutableData alloc] initWithLength: someLength];
void* bitmapData = [mutableData mutableBytes];
[mutableData release];
//...

在这里使用的正确方法是NSMutableData什么?

我认为使用NSMutableData而不是malloc()并且free()会很方便,因为它会自动发布。但现在我不确定这是否属实。

4

2 回答 2

1

当您说mutableData似乎没有被释放时,您的意思是在 点CGContextRelease(),还是您的意思是它永远不会释放并且每次运行时都会泄漏?

在您的第一个示例中,您不会期望mutableData在自动释放池耗尽(通常在事件循环结束时)之前解除分配,因为您使用了-dataWithLength:. 在您的第二个示例中,不确定是否mutableData会被释放。调用-mutableBytes可能会应用保留和自动释放以确保指针对事件循环的其余部分有效(这在这类方法中很常见),但文档没有说,所以你的第二个例子是未定义的行为,如果你bitmapData以后用。

现在,如果mutableData泄漏,那么您可能会在其他地方过度保留它。

于 2011-02-04T15:03:52.077 回答
0

向 NSMutableData 的实例询问其 mutableBytes 只会返回一个指向它为您管理的现有(已分配)缓冲区的指针。从管理的角度来看,它对内存没有任何影响。

因此,在您的第一个示例中,在 Instruments 中查看 mutableData 时似乎没有被释放的事实可能与当时的自动释放池环境有关。以这种方式使用 mutableData 的代码是否有 NSAutoreleasePool?您是否在控制台中看到警告,例如“在没有设置池的情况下调用自动释放;只是泄漏”?如果是这样,您只需将代码包装在:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// bitmap drawing code here
[pool drain];

在第二个示例中,您可以在 NSMutableData 实例上使用 alloc/init,但您需要在使用从 mutableBytes 获得的指针完成后释放它。调用释放后,指针将指向已释放(释放)的内存,访问它会导致可怕的 EXC_BAD_ACCESS。

此外,在这里使用 malloc/free 可能是我的首选,因为您可以非常明确地了解如何以及何时分配和释放内存。NSMutableData + autorelease 并没有真正为您购买任何东西,除了一些开销,如果您没有将该对象用于其他任何事情。

于 2011-02-04T15:03:54.557 回答