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

发布于 2024-10-16 01:33:20 字数 752 浏览 6 评论 0原文

我一直在使用

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

I've been using

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

I have an autorelease pool in place, but when looking at this in Instruments, mutableData doesn't seem to be deallocated.
I thought of using alloc/init like below, but I'm not sure if sending release would purge bitmapData as well.

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

What's the proper way of using NSMutableData here?

I thought using NSMutableData instead of malloc() and free() would be convenient because it'll be autoreleased. but now I'm not sure if that's true.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱格式化 2024-10-23 01:33:20

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

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

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

When you say mutableData doesn't seem to be deallocated, do you mean at the point of CGContextRelease(), or do you mean it never deallocates and it leaks every time you run this?

In your first example, you would not expect mutableData to deallocate until the autorelease pool drains (generally at the end of the event loop), because you used -dataWithLength:. In your second example, it's undefined whether mutableData would be released. The call to -mutableBytes might apply a retain and autorelease to ensure the pointer is valid for the rest of the event loop (this is pretty common with these kinds of methods), but the docs don't say, so your second example is undefined behavior if you use bitmapData later.

Now if mutableData leaks, then you're likely over-retaining it somewhere else.

请叫√我孤独 2024-10-23 01:33:20

向 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 不会真正为您购买任何东西,除了一些开销之外。

Asking an instance of NSMutableData for its mutableBytes simply returns a pointer to the existing (already allocated) buffer that it manages for you. It does not have any effect on the memory from a management perspective.

So, in your first example, the fact that mutableData doesn't appear to be deallocated when looking at it in Instruments could be related to the autorelease pool environment at the time. Does the code using mutableData in that way have an NSAutoreleasePool in place? Do you see warnings in the console like "autorelease called with no pool in place; just leaking"? If so, you just need to wrap the code in:

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

In the second sample, you could use alloc/init on the NSMutableData instance, but you would need to release it after you were done using the pointer you get from mutableBytes. The pointer will be pointing to deallocated (freed) memory after you call release, and accessing it will result in the dreaded EXC_BAD_ACCESS.

Also, using malloc/free would probably be my first choice here, since you get to be very explicit about how and when the memory is allocated and freed. NSMutableData + autorelease isn't really buying you anything except some overhead, if you aren't using the object for anything else.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文