我有一个非常简单的 installTapOnBus
闭包,可以成功更新控制台,但不能更新 UI 元素。这是代码:
self.meter.text="..."
let inputNode = audioEngine.inputNode
let bus = 0
inputNode!.installTapOnBus(bus, bufferSize: 2048, format: inputNode!.inputFormatForBus(bus)) {
(buffer: AVAudioPCMBuffer!, time: AVAudioTime!) -> Void in
var someFeature:Float=0.0
for var i=0; i<Int(buffer.frameLength); i += 1{
someFeature += fabs(buffer.floatChannelData.memory[i])
}
someFeature /= Float(buffer.frameLength)
self.meter.text="\(someFeature)" // No effect!
print("\(someFeature)") // This works
}
也许我需要将对 self
的弱引用发送到闭包,但不确定语法。任何关于如何更新 UI 元素的反馈/想法都会很棒!感谢阅读。
最佳答案
您应该只从主线程进行 UIKit 调用。
来自 UIView 的 documentation :
Threading Considerations
Manipulations to your application’s user interface must occur on the main thread. Thus, you should always call the methods of the UIView class from code running in the main thread of your application. The only time this may not be strictly necessary is when creating the view object itself but all other manipulations should occur on the main thread.
如果您查看 AVAudioNode
的 API 引用特别是 installTapOnBus
:
The tapBlock may be invoked on a thread other than the main thread.
您的 UI 未更新,因为来自 inputNode!.installTapOnBus()
的回调在后台线程上执行,然后您尝试从该线程更新 UI。
正如您所发现的,您将希望通过以下方式从主线程进行 UI 调用:
dispatch_async(dispatch_get_main_queue(), ^{
/* Make UIKit calls here */
});
关于ios - 从 installTapOnBus 闭包中访问类属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34885070/