iOS内存不足错误

时间:2017-03-07 05:29:59

标签: ios iphone visualizer

我最近需要在iOS swift中实现音乐可视化工具,如image / gif所示。

enter image description here

我使用此TempiFFT来取代音频输入并修改UI以获得所需的视觉效果。 视觉效果的主要特征是: 1)条的梯度 2)条形图中的虚线效果 3)淡出前几个栏目

对于褪色效果我使用此How To Make A Simple Drawing App with UIKit and Swift,它最初在临时图像上绘制,然后复制到主图像,不透明度降低(如果需要)。

我以某种方式成功实现了这些功能。这些酒吧工作正常,但是" didReceiveMemoryWarning"在某个时间(大约3分钟)后调用,应用程序在此之后几秒钟停止。

那么我该如何解决内存警告问题并且应用程序停止发布问题

以下是绘制条形码的代码:

    func drawBars() {
    // start drawng on temp image
    UIGraphicsBeginImageContext(self.tempImage.frame.size)
    // get context
    let context = UIGraphicsGetCurrentContext()
    tempImage.image?.draw(in: CGRect(x:0, y:0, width: tempImage.frame.width, height:tempImage.frame.height))


    let height = Double(self.tempImage.frame.size.height)
    let width = Double(self.tempImage.frame.size.width)

    let barWidth = width / bars
    //let barSpace = width / bars * 0.2

    // number of bars
    let count = self.fft?.numberOfBands ?? 0

    // number of magnitudes
    let fft = self.fft?.bandMagnitudes ?? [0, 0, 0]


    if count == 0 {
        return
    }

    // Draw the spectrum.
    let maxDB: Float = 64.0
    let minDB: Float = -32.0
    let headroom = maxDB - minDB
    //let colWidth = tempi_round_device_scale(d: CGFloat(width) / CGFloat(count))

    // need to display only few (10) bars so will consider very (count/10)th bar
    let divider = count / Int(bars) - 1
    var barCount = 0

    for i in 0..<count {
        // checking if display bar or not
        if i % divider != 0 || i / divider > 9 {
            continue
        }

        let magnitude = fft[i]

        // Incoming magnitudes are linear, making it impossible to see very low or very high values. Decibels to the rescue!
        var magnitudeDB = TempiFFT.toDB(magnitude)

        // Normalize the incoming magnitude so that -Inf = 0
        magnitudeDB = max(0, magnitudeDB + abs(minDB))

        let dbRatio = min(1.0, magnitudeDB / headroom)
        let magnitudeNorm = CGFloat(dbRatio) * CGFloat(height)

        //let colRect: CGRect = CGRect(x: x, y: plotYStart, width: colWidth, height: magnitudeNorm)

        //let startPoint = CGPoint(x: viewWidth / 2, y: 0)
        //let endPoint = CGPoint(x: viewWidth / 2, y: viewHeight)

        //context.saveGState()
        //context.clip(to: colRect)
        //context.drawLinearGradient(gradient!, start: startPoint, end: endPoint, options: CGGradientDrawingOptions(rawValue: 0))
        //context.restoreGState()

        //x += colWidth
        //}

        //for var i in (0..<10) {

        //print(barCount)

        let x = Double(barCount) * barWidth + 0.5 * barWidth

        // cliping the bar area for dash and gradient effect
        context?.saveGState()
        context?.addRect(CGRect(x:x - width / bars * 0.4, y:height - Double(magnitudeNorm), width:width / bars * 0.8, height:Double(magnitudeNorm)))
        context?.clip()
        //            context?.drawLinearGradient(CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: [UIColor.red.cgColor, UIColor.blue.cgColor] as CFArray, locations: [0, 1])! , start: CGPoint(x:x, y:height + 5), end: CGPoint(x:x, y:height - Double(magnitudeNorm)), options: CGGradientDrawingOptions(rawValue: 0))
        // draw the gradient first
        context?.drawLinearGradient(CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: [UIColor.white.cgColor, UIColor.cyan.cgColor, UIColor.magenta.cgColor, UIColor.magenta.cgColor] as CFArray, locations: [0, 0.5, 0.85,   1])! , start: CGPoint(x:x, y:height + 5), end: CGPoint(x:x, y:0), options: CGGradientDrawingOptions(rawValue: 0))

        context?.restoreGState()

        //context?.addRect(CGRect(x:x - width / bars * 0.4, y:height - Double(magnitudeNorm), width:width / bars * 0.8, height:Double(magnitudeNorm)))
        //context?.drawPath(using: CGPathDrawingMode.stroke)

        // now draw the dash line
        context?.move(to: CGPoint(x:x, y:height + 5))
        context?.addLine(to: CGPoint(x:x, y:height - Double(magnitudeNorm)))
        //context?.addLine(to: CGPoint(x:x, y:height - Double((i / divider + 1) * 10)))

        context?.setLineCap(CGLineCap.butt)
        context?.setLineWidth(CGFloat(width / bars * 0.85))
        context?.setStrokeColor(red: 0, green: 0, blue: 0, alpha: 1)
        context?.setBlendMode(CGBlendMode.normal)
        context?.setLineDash(phase: 1, lengths: [5, 10])

        context?.strokePath()

        barCount += 1;

    }

    // save the image
    tempImage.image = UIGraphicsGetImageFromCurrentImageContext()

    tempImage.alpha = 1
    UIGraphicsEndImageContext()

    tempi_dispatch_main { () -> () in
        //self.spectralView.fft = fft
        //self.spectralView.setNeedsDisplay()
        //merge the image with the previous image
        //on main thread
        self.refresh()
    }

    //refresh()

}

func refresh() {
    UIGraphicsBeginImageContext(mainImage.frame.size)
    //let context = UIGraphicsGetCurrentContext()
    // draw the previous image with 0.9 opacity(transparancy) for a fade out effect
    mainImage.image?.draw(in: CGRect(x:0, y:0, width:mainImage.frame.width, height:mainImage.frame.height), blendMode: CGBlendMode.normal, alpha: 0.9)
    // draw the new bars over the previous one
    tempImage.image?.draw(in: CGRect(x:0, y:0, width:mainImage.frame.width, height:mainImage.frame.height), blendMode: CGBlendMode.normal, alpha: 1)
    // finally show that new image on the image view
    mainImage.image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    tempImage.image = nil
}

0 个答案:

没有答案