CGContextDrawImage(Swift)上的间歇性“释放对象的校验和不正确”错误

Posted

技术标签:

【中文标题】CGContextDrawImage(Swift)上的间歇性“释放对象的校验和不正确”错误【英文标题】:intermittent "incorrect checksum for freed object" error on CGContextDrawImage (Swift) 【发布时间】:2015-04-09 08:05:25 【问题描述】:

我确实遇到了我的应用程序罕见的崩溃 - 在我将 UIImage 转换为像素数组的方法中不时发生这种情况,这样我就可以一个一个地使用像素(它是一个着色书应用程序)。

我的转换代码如下

init(image: UIImage)
    let imageref = image.CGImage
    self.width = CGImageGetWidth(imageref)
    self.height = CGImageGetHeight(imageref)
    // create new bitmap context
    let bitsPerComponent = UInt(8)
    let bytesPerPixel = UInt(4)
    let bitsPerPixel = bitsPerComponent * bytesPerPixel
    let bytesPerRow = UInt(self.width * bytesPerPixel)
    let byteCount = UInt(bytesPerRow * self.height)
    let colorSpace = CGColorSpaceCreateDeviceRGB()
    let bitmapInfo: CGBitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawValue)
    let context = CGBitmapContextCreate(nil, self.width, self.height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo)

    // draw image to context
    let rect = CGRectMake(0, 0, CGFloat(self.width), CGFloat(self.height))
    CGContextDrawImage(context, rect, imageref)
    // manipulate binary data
    let tmpPixelsArray: UnsafeMutablePointer<ARGB> = UnsafeMutablePointer<ARGB>(CGBitmapContextGetData(context))
    self.pixels = UnsafeMutablePointer<ARGB>.alloc(Int(byteCount));

崩溃发生在

        CGContextDrawImage(context, rect, imageref)

行,错误消息为“malloc: *** error for object 0x7aa3b000: 已释放对象的校验和不正确 - 对象可能在被释放后被修改。”

没有通用的复制模式。有时它发生在第 10 次迭代,有时发生在第 5 次,有时发生在第 20 次。知道如何进一步调试吗?

【问题讨论】:

错误消息通常表明您覆盖了分配内存的末尾,或者表明您写入已释放的内存。由于您在这里没有足够的代码来重现问题,因此很难确切地说出在哪里或如何。除了“操纵二进制数据”部分之外,这里没有任何问题,这确实是最有可能的罪魁祸首。 David - 感谢您的评论 - 了解有关我如何“操作二进制数据”的更多详细信息引导我找到解决方案!非常感谢! 【参考方案1】:

问题 #1 是每次都创建 self.pixels 表。我现在检查当前数组大小。

问题 #2 是该数组缺少内存管理(销毁和释放)。

修复了一段代码 - 而不是:

self.pixels = UnsafeMutablePointer<ARGB>.alloc(Int(byteCount));

我现在有:

if (byteCount>self.previousMaxByteCount)
        println("ALLOC: \(byteCount)")
        self.previousMaxByteCount = byteCount
        self.pixels.destroy()
        self.pixels.dealloc(1)
        self.pixels = nil
        self.pixels = UnsafeMutablePointer<ARGB>.alloc(Int(byteCount));
    

我还了解到 Swift/Xcode 报告的崩溃位置并不像我之前的 Java 经验那样可靠,而且问题并不完全在最初指出的那一行。

【讨论】:

我使用 malloc 而不是 alloc,这就是问题所在。谢谢!

以上是关于CGContextDrawImage(Swift)上的间歇性“释放对象的校验和不正确”错误的主要内容,如果未能解决你的问题,请参考以下文章

巨大的内存峰值 - CGContextDrawImage

CGContextDrawImage 画大图很模糊

-[UIImage drawInRect:] / CGContextDrawImage() 不释放内存?

CGContextDrawImage 的优化替代方案

CGContextDrawImage 崩溃

与 CGContextDrawImage 相比,为啥 UIImageView 如此占用内存