具有指定大小的自动释放 UIImages 的奇怪 malloc 错误
Posted
技术标签:
【中文标题】具有指定大小的自动释放 UIImages 的奇怪 malloc 错误【英文标题】:Strange malloc error with autoreleased UIImages of specified size 【发布时间】:2009-09-29 20:42:24 【问题描述】:我正在追踪一个奇怪的错误。该错误通过在控制台日志中显示此消息来表现出来:
BlurApp(5018,0xa00d6500) malloc: *** error for object 0x103b000: pointer being freed was not allocated
执行离开我的事件循环后会弹出此消息。它似乎在自动释放池被耗尽时发生。这是似乎触发错误的代码:
- (UIImage*)imageWithImage:(UIImage*)image
scaledToSize:(CGSize)newSize;
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
我这样调用 imageWithImage:
UIImage* theImage = [self imageWithImage:origImage scaledToSize:rect.size];
theImage 在调用例程中使用,然后我假设 autorelease 会处理它。
如果我将return newImage;
更改为返回[newImage retain];
,则看不到错误消息。
现在,这很奇怪。此错误仅发生在某些大小的 newSize 中。具体来说,当 newSize 的高度和宽度等于 55 到 176 范围内的任何数字(不包括 56、110、112、114)时,它总是会发生,而不是在 5 到 300 之间的其他高度和宽度值。(高度和宽度是所有测试总是相等的)
我可以用新的眼光来看待这个...谢谢!
【问题讨论】:
这似乎是 Simulator 3.0 SDK 中的一个错误。我在模拟器的 SDK 3.1 中看不到这些错误消息,在 iPhone 上也看不到错误消息。 【参考方案1】:尝试打印从 UIGraphicsGetImageFromCurrentImageContext 返回的图像的 retainCount。
类似:NSLog(@"Image retain count: %u", [newImage retainCount]);
或在代码上设置断点并在 gdb 控制台输入以下内容:
print (int) [newImage retainCount]
retainCount 应该大于零,可能是一。单步执行代码并继续检查 retainCount 以查看它何时达到零。
有一个类似的线程: iPhone development: pointer being freed was not allocated
【讨论】:
底部的链接指向一个类似的问题,这让我认为这是模拟器中的一个错误。我应该提到我在模拟器上运行它。我在 iPhone 上试用了该应用程序。那里没有错误。我还尝试使用 Simulator 3.1 SDK 而不是 3.0。 Simulator 3.1 下没有错误。【参考方案2】:theImage 在调用例程中使用,然后我假设 autorelease 会处理它。
如果我改变返回 newImage;返回 [newImage 保留];看不到错误信息。
现在,这很奇怪。此错误仅发生在某些大小的 newSize 中。
在垃圾收集语言中,只要不再引用对象,垃圾收集器就可以清理(释放)对象。为了提高性能,垃圾收集可能会延迟——即直到有空闲时间、经过一定时间或内存条件达到某个阈值。
因此,一些对象可能会立即被释放,而另一些对象可能会在很久以后被释放或永远不会被释放(直到环境关闭)。
【讨论】:
这是给 iPhone 的,它没有垃圾回收功能。以上是关于具有指定大小的自动释放 UIImages 的奇怪 malloc 错误的主要内容,如果未能解决你的问题,请参考以下文章
通过UIStackView在同等大小的UIImages下安排自定义大小的UILabels
当自动释放池耗尽时,NSFileAttributes dealloc 中的 SIGSEGV SEGV_ACCERR 崩溃?
具有大量自动释放对象的线程如果是/否,在这种情况下是不是必须使用自动释放池,为啥?