我创建了UIView
,宽度= 3500。
在视图中,我使用带有CAShapeLayer
的{{1}}绘制SoundWave,其中包含70008个样本间隔0.05(70008 * 0.05 = 3500)。
UIBezierPath
的lineWidth是0.10。
使用UIBezierPath
宽度140016256帧容量只读取一次内容。
当读取AVAudioPCMBuffer
时,每1的2000个值“未读取”(140016256/2000 = 70008)
AVAudioPCMBuffer
的内容是UIView
的contextSize,因此当用户拖入滚动视图时,他可以看到SoundWave的不同部分。
问题是滚动时需要很长时间才能完成滚动。
以下是代码:
UIScrollView
有什么我可以做的不同优化代码或我用于许多资源?
编辑:
func drawSoundWave(fromSample:Int64, toSample:Int64){
// Drawing code
print("\(logClassName): Drawing from = \(fromSample) to \(toSample)")
if readFile != nil{
let soundPath = UIBezierPath()
soundPath.lineWidth = lineWidth
soundPath.move(to: CGPoint(x:0.0 , y: middleY))
let testTo = Int64(toSample)
let sequence = stride(from: fromSample, to: testTo, by: 2000)
var testIndex = 0
for element in sequence {
let newSample = CGFloat(readFile?.audioBuffer.floatChannelData?.pointee.advanced(by: Int(element)).pointee ?? 0)
print("\(logClassName): newSample = \(newSample) -> TestIndex = \(testIndex) in Element = \(element)")
/** Continuous View **/
let nextPoint = CGPoint(x: soundPath.currentPoint.x + sampleSpace,
y: middleY - (newSample * 100) - 1.0)
soundPath.addLine(to: nextPoint)
soundPath.move(to: nextPoint)
testIndex += 1
}
let trackLayer = CAShapeLayer()
trackLayer.path = soundPath.cgPath
trackLayer.strokeColor = UIColor.lightGray.cgColor
trackLayer.lineWidth = 0.10
trackLayer.fillColor = UIColor.green.cgColor
trackLayer.lineCap = kCALineCapRound
self.layer.addSublayer(trackLayer)
}
}
位于名为readFile的结构中。
在Draw方法
答案 0 :(得分:1)
有什么我可以做的不同优化代码或我用于许多资源?
您可以做的第一件事就是对代码进行分析,以找出大部分时间花在哪里的代码。您是否一次从一个文件中读取样本的问题是什么?也许使用2000的步幅会导致文件缓冲区的大部分好处丢失,因此从文件中读取每个第2000个样本比您意识到的更昂贵?或者是你每次创建一个新的bezier路径或形状层?也许这只是每个样本需要时间的打印声明? 在知道代码缓慢之前,你真的不知道如何加速代码。
请记住,在滚动期间,您的绘制方法将被重复调用,并且应该尽可能少地进行实际工作。如果您的代码在仅需要绘制新暴露的数据时重新计算整个可见区域的数据,那么这是一个大幅提升速度的机会。在滚动期间以较低分辨率绘制,然后在滚动停止时以全分辨率重绘可以提供帮助。保持低分辨率(就样本而言)bezier路径而不是一直创建新路径可能会有所帮助。但同样:先测量,然后再提高。
跳出来的一件事是你将70,000个数据点绘制到3500像素宽的视图中。每个宽度像素的20个数据点远比用户即使在视图不移动时也能识别的数据更多;当用户滚动时,他们几乎看不到任何数据。即使你必须查看那么多样本来找到波的波峰和波谷,你肯定不需要在路径上添加那么多点。