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() 调用的路径指令和数据。
我正在开发一个应用程序,它在 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() 调用的路径指令和数据。