使用NSMutableData实例的字节,同时允许它自动释放

时间:2011-02-04 14:52:56

标签: objective-c cocoa-touch memory-management nsmutabledata

我一直在使用

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

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

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

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

我认为使用NSMutableData代替malloc()free()会很方便,因为它会被自动释放。但现在我不确定这是不是真的。

2 个答案:

答案 0 :(得分:1)

当你说mutableData似乎没有被解除分配时,你的意思是CGContextRelease(),或者你的意思是它永远不会解除分配并且每次运行它都会泄漏?

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

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

答案 1 :(得分:0)

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

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

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

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

另外,使用malloc / free可能是我的第一选择,因为你必须非常明确地分配和释放内存的方式和时间。除了一些开销之外,NSMutableData + autorelease并没有真正购买任何东西,如果你没有使用该对象的话。