【问题标题】:Using the bytes of an NSMutableData instance while allowing it to be autoreleased使用 NSMutableData 实例的字节,同时允许它被自动释放
【发布时间】:2011-02-04 14:52:56
【问题描述】:

我一直在用

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() 会很方便,因为它会自动释放。但现在我不确定这是不是真的。

【问题讨论】:

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


    【解决方案1】:

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

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

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

    【讨论】:

    • 是的,即使在 CGContextRelease() 之后,它也不会解除分配。除了上下文创建函数,我不会将原始数据或 NSMutableData 传递给其他任何东西。
    • 您所说的“从不”是指即使在事件循环完成之后,当您多次调用它时,您的整体内存使用量会继续增长?
    • grr,在其他地方有其他泄漏,保留了从上下文创建的图像,不确定是否保留原始字节,因此也保留可变数据。但是在消除了其他泄漏之后,仪器不会将 mutableData 显示为活动的......也许仪器被混淆了
    【解决方案2】:

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

    因此,在您的第一个示例中,在 Instruments 中查看 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 并没有真正为您购买任何东西,除了一些开销,如果您没有将该对象用于其他任何事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-06
      • 2011-09-15
      • 2015-04-04
      • 1970-01-01
      相关资源
      最近更新 更多