我有一个非常简单的更新方法,其中包含了调试行。
@IBOutlet weak var meterLabel: UILabel!
func updateMeter(string: String)
{
if Thread.isMainThread {
meterLabel.text = string
} else {
DispatchQueue.main.sync {
meterLabel.text = string
}
}
print(string)
}
显然string
永远不会为零。函数updateMeter
每秒大约调用3次,但是目前在模拟器中我看不到UILabel更改(它在其他地方调用相同的updateMeter
时确实发生了更改)。是否有任何原因导致更改UILabel的文本在主线程上看不到结果?
在这里打电话:
public func startRecording()
{
let recordingPeriod = TimeInterval(Float(Constants.windowSize)/Float(Constants.sampleFrequency))
var index = 0
Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { timer in
let audioRecorder = self.AudioRecorders[index]!
audioRecorder.deleteRecording()
audioRecorder.record()
DispatchQueue.main.asyncAfter(deadline: .now() + recordingPeriod)
{
if let pitch = self.finishSampling(audioRecorder: audioRecorder, index: self.AudioRecorders.index(of: audioRecorder))
{
self.meterViewController?.updateMeter(string: String(pitch))
}
}
index = index + 1
if index == 4 { index = 0 }
if !(self.keepRecording ?? false) { timer.invalidate() }
}
}
其他称为:
的方法private func finishSampling(audioRecorder: AVAudioRecorder?, index: Int?) -> Float?
{
audioRecorder?.stop()
if let index = index, var (data, _, _) = loadAudioSignal(audioURL: getDirectory(for: index))
{
let pitch = getPitch(&data, Int32(data.count), Int32(Constants.windowSize), Int32(Constants.sampleFrequency))
return Float(pitch)
}
return nil
}
private func loadAudioSignal(audioURL: URL) -> (signal: [Float], rate: Double, frameCount: Int)?
{
guard
let file = try? AVAudioFile(forReading: audioURL),
let format = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: file.fileFormat.sampleRate, channels: file.fileFormat.channelCount, interleaved: false),
let buf = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: UInt32(file.length))
else
{
return nil
}
try? file.read(into: buf)
let floatArray = Array(UnsafeBufferPointer(start: buf.floatChannelData?[0], count:Int(buf.frameLength)))
return (signal: floatArray, rate: file.fileFormat.sampleRate, frameCount: Int(file.length))
}
getPitch
进行一些简单的处理并相对较快地运行。
答案 0 :(得分:0)
通过调用usleep
,您正在阻塞主线程。主线程是更新UI的线程。由于已被阻止,因此无法执行此操作。
您应该使用一种替代方法,例如Timer
来定期更新标签。