菜鸟教程小白 发表于 2022-12-11 19:28:11

ios - Swift 3 CGContext 内存泄漏


                                            <p><p>我正在使用 CGBitMapContext() 将颜色空间转换为 ARGB 并获取像素数据值,我为位图上下文分配空间并在完成后释放它,但我仍然在仪器中看到内存泄漏我想我可能做错了什么,所以任何帮助都将不胜感激。 </p>

<p>这里是 ARGBBitmapContext 函数</p>

<pre><code>func createARGBBitmapContext(width: Int, height: Int) -&gt; CGContext {
    var bitmapByteCount = 0
    var bitmapBytesPerRow = 0

    //Get image width, height
    let pixelsWide = width
    let pixelsHigh = height

    bitmapBytesPerRow = Int(pixelsWide) * 4
    bitmapByteCount = bitmapBytesPerRow * Int(pixelsHigh)


    let colorSpace = CGColorSpaceCreateDeviceRGB()
    // Here is the malloc call that Instruments complains of
    let bitmapData = malloc(bitmapByteCount)


    let context = CGContext(data: bitmapData, width: pixelsWide, height: pixelsHigh, bitsPerComponent: 8, bytesPerRow: bitmapBytesPerRow, space: colorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue)

    // Do I need to free something here first?
    return context!
}
</code></pre>

<p>这里是我使用上下文检索所有像素值作为 UInt8 列表的地方(以及内存泄漏的地方)</p>

<pre><code>extension UIImage {

    func ARGBPixelValues() -&gt; {
      let width = Int(self.size.width)
      let height = Int(self.size.height)
      var pixels = (repeatElement(0, count: width * height * 3))

      let rect = CGRect(x: 0, y: 0, width: width, height: height)
      let context = createARGBBitmapContext(inImage: self.cgImage!)
      context.clear(rect)
      context.draw(self.cgImage!, in: rect)

      var location = 0

      if let data = context.data {

            while location &lt; (width * height) {
                let arrOffset = 3 * location
                let offset = 4 * (location)

                let R = data.load(fromByteOffset: offset + 1, as: UInt8.self)
                let G = data.load(fromByteOffset: offset + 2, as: UInt8.self)
                let B = data.load(fromByteOffset: offset + 3, as: UInt8.self)

                pixels   = R
                pixels = G
                pixels = B

                location += 1
            }

            free(context.data) // Free the data consumed, perhaps this isn&#39;t right?
      }

      return pixels
    }
}
</code></pre>

<p>Instruments 报告了 1.48MiB 的 malloc 错误,这适合我的图像大小 (540 x 720) 我释放了数据,但显然这不正确。 </p>

<p>我应该提一下,我知道你可以将 nil 传递给 CGContext init(它会管理内存),但我更好奇为什么使用 malloc 会产生问题,我应该知道更多的东西(我更熟悉 Obj -C)。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>因为 CoreGraphics 不是由 ARC 处理的(就像所有其他 C 库一样),所以即使在 Swift 中,您也需要使用自动释放来包装您的代码。特别是如果您不在主线程上(如果涉及 CoreGraphics,您不应该在主线程上...... .userInitiated 或更低是合适的)。</p>

<pre><code>func myFunc() {
    for _ in 0 ..&lt; makeMoneyFast {
      autoreleasepool {
            // Create CGImageRef etc...
            // Do Stuff... whir... whiz... PROFIT!
      }
    }
}
</code></pre>

<p>对于那些关心的人,你的 Objective-C 也应该像这样包装:</p>

<pre><code>BOOL result = NO;
NSMutableData* data = [ init];
@autoreleasepool {
    CGImageRef image = [self CGImageWithResolution:dpi
                                          hasAlpha:hasAlpha
                                     relativeScale:scale];

    NSAssert(image != nil, @&#34;could not create image for TIFF export&#34;);

    if (image == nil)
      return nil;

    CGImageDestinationRef destRef = CGImageDestinationCreateWithData((CFMutableDataRef)data, kUTTypeTIFF, 1, NULL);
    CGImageDestinationAddImage(destRef, image, (CFDictionaryRef)options);
    result = CGImageDestinationFinalize(destRef);
    CFRelease(destRef);
}

if (result) {
    return ;
} else {
    return nil;
}
</code></pre>

<p>见 <a href="https://stackoverflow.com/questions/25860942/is-it-necessary-to-use-autoreleasepool-in-a-swift-program" rel="noreferrer noopener nofollow">this answer</a>了解详情。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - Swift 3 CGContext 内存泄漏,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/43339784/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/43339784/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - Swift 3 CGContext 内存泄漏