swift 中 UIBezierPath 的内存泄漏

Memory Leak with UIBezierPath in swift

我正在开发一个应用程序,它在 window 中绘制波形,可以滑入和滑出主视图。我发现如果我多次打开滑动视图,应用程序开始变慢。我发现使用 UIBezierPath 绘制波形会减慢我的应用程序。我想知道是否需要做些什么来终止当前的 UIBezierPath 并避免内存泄漏。感谢任何建议或建议我对使用 UIBezierPath 不是很熟悉。在此先感谢您的帮助!!!

import UIKit

class WaveView: UIView {
    enum WaveType{
        case sin
        case triangle
        case square
        case noise
        case sawtooth
    }
    var waveType: WaveType = .sin { didSet { setNeedsDisplay() } }
    var color = UIColor.black { didSet { setNeedsDisplay() } }
    let path = UIBezierPath()
    
    var isSelected = false {
        didSet {
            let tempColor: UIColor = self.backgroundColor!
            self.backgroundColor = color
            color = tempColor
        }
    }
    
    private var labelColor: UIColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)

    override func draw(_ rect: CGRect) {
        let middle: CGPoint = CGPoint(x: rect.midX, y: rect.midY)
        let width = rect.width
        let height = rect.height
        let graphWidth: CGFloat = 0.6
        let amplitude: CGFloat = 0.2
        let midOrigin = CGPoint(x: width * (1 - graphWidth) / 2, y: height * 0.50)
        
        switch waveType {
        case .sin:
            path.move(to: midOrigin)
            for angle in stride(from: 5.0, through: 360.0, by: 5.0) {
                let x = midOrigin.x + CGFloat(angle/360.0) * width * graphWidth
                let y = midOrigin.y - CGFloat(sin(angle/180.0 * Double.pi)) * height * amplitude
                path.addLine(to: CGPoint(x: x, y: y))
            }
        case .triangle:
            let d = rect.width * 0.2
            path.move(to: CGPoint(x: middle.x, y: middle.y - d))
            path.addLine(to: CGPoint(x: middle.x + d, y: middle.y + d))
            path.move(to: CGPoint(x: middle.x, y: middle.y - d))
            path.addLine(to: CGPoint(x: middle.x - d, y: middle.y + d))
        case .square:
            let d = rect.width * 0.2
            path.move(to: CGPoint(x: middle.x - d, y: middle.y + d))
            path.addLine(to: CGPoint(x: middle.x - d/3, y: middle.y + d))
            path.addLine(to: CGPoint(x: middle.x - d/3, y: middle.y - d))
            path.addLine(to: CGPoint(x: middle.x + d/3, y: middle.y - d))
            path.addLine(to: CGPoint(x: middle.x + d/3, y: middle.y + d))
            path.addLine(to: CGPoint(x: middle.x + d, y: middle.y + d))
        case.sawtooth:
            let d = rect.width * 0.2
            path.move(to: CGPoint(x: middle.x - d, y: middle.y + d))
            path.addLine(to: CGPoint(x: middle.x + d, y: middle.y - d))
            path.addLine(to: CGPoint(x: middle.x + d, y: middle.y + d))
        case .noise:
            path.move(to: midOrigin)
            for angle in stride(from: 3.0, through: 360.0, by: 3.0) {
                let x = midOrigin.x + CGFloat(angle/360.0) * width * graphWidth
                let y = midOrigin.y - CGFloat(Float.random(in: -1..<1)) * height * amplitude
                path.addLine(to: CGPoint(x: x, y: y))
            }
        }
        
        color.setStroke()
        path.lineCapStyle = .round
        path.stroke()
    }
}

不要将路径实例设为 class 成员变量 - 只需在 draw() 方法中声明一个本地 UIBezierPath 变量即可。

override func draw(_ rect: CGRect) {
    let path = UIBezierPath()
    // etc.
}

这将确保释放用于一次 draw() 调用的路径指令和数据。