使用 NSMutableData 实例的字节,同时允许它自动释放
我一直在使用
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您说
mutableData
似乎没有被释放时,您是指在CGContextRelease()
点,还是意味着它永远不会释放并且每次您都会泄漏运行这个?在第一个示例中,您不会期望
mutableData
在自动释放池耗尽之前(通常在事件循环结束时)释放,因为您使用了-dataWithLength:
。在第二个示例中,未定义是否会释放mutableData
。对-mutableBytes
的调用可能会应用保留和自动释放,以确保指针对于事件循环的其余部分有效(这在此类方法中很常见),但文档没有说,因此如果您稍后使用bitmapData
,您的第二个示例是未定义的行为。现在,如果
mutableData
泄漏,那么您可能会在其他地方过度保留它。When you say
mutableData
doesn't seem to be deallocated, do you mean at the point ofCGContextRelease()
, 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 whethermutableData
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 usebitmapData
later.Now if
mutableData
leaks, then you're likely over-retaining it somewhere else.向 NSMutableData 实例询问其 mutableBytes 只是返回一个指向它为您管理的现有(已分配)缓冲区的指针。从管理的角度来看,它对内存没有任何影响。
因此,在您的第一个示例中,当在 Instruments 中查看 mutableData 时,它似乎没有被释放,这一事实可能与当时的自动释放池环境有关。以这种方式使用 mutableData 的代码是否有 NSAutoreleasePool ?您是否在控制台中看到类似“在没有池的情况下调用自动释放;只是泄漏”之类的警告?如果是这样,您只需将代码包装在:
在第二个示例中,您可以在 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:
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.