我一直在使用
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()
会很方便,因为它会被自动释放。但现在我不确定这是不是真的。
答案 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并没有真正购买任何东西,如果你没有使用该对象的话。