如何在 Swift 中关闭和完成处理程序后获取数据
Posted
技术标签:
【中文标题】如何在 Swift 中关闭和完成处理程序后获取数据【英文标题】:How to get data after after closure & completion handler in Swift 【发布时间】:2020-09-06 18:08:46 【问题描述】:我是 Swift 的新手,我试图找到一个解决方案,但没有成功解决这个问题。
我在 ViewDidLoad() 中:
AudioContext.load(fromAudioURL: self.url) audioContext in
guard let audioContext = audioContext else
fatalError("Couldn't create the audioContext")
self.outputArray = self.render(audioContext: audioContext, targetSamples: 300)
samples = self.outputArray.map -Int($0)
print("TOTAL1:\(samples)") **// IT WORKS OK**
print("TOTAL2:\(samples)") // IT DOES NOT WORK => Give nothing
以及带有完成处理程序的函数:
public static func load(fromAudioURL audioURL: URL, completionHandler: @escaping (_ audioContext: AudioContext?) -> ())
let asset = AVURLAsset(url: audioURL, options: [AVURLAssetPreferPreciseDurationAndTimingKey: NSNumber(value: true as Bool)])
guard let assetTrack = asset.tracks(withMediaType: AVMediaType.audio).first else
fatalError("Couldn't load AVAssetTrack")
asset.loadValuesAsynchronously(forKeys: ["duration"])
var error: NSError?
let status = asset.statusOfValue(forKey: "duration", error: &error)
switch status
case .loaded:
guard
let formatDescriptions = assetTrack.formatDescriptions as? [CMAudioFormatDescription],
let audioFormatDesc = formatDescriptions.first,
let asbd = CMAudioFormatDescriptionGetStreamBasicDescription(audioFormatDesc)
else break
let totalSamples = Int((asbd.pointee.mSampleRate) * Float64(asset.duration.value) / Float64(asset.duration.timescale))
let audioContext = AudioContext(audioURL: audioURL, totalSamples: totalSamples, asset: asset, assetTrack: assetTrack)
completionHandler(audioContext)
return
case .failed, .cancelled, .loading, .unknown:
print("Couldn't load asset: \(error?.localizedDescription ?? "Unknown error")")
@unknown default:
print("Couldn't load asset: \(error?.localizedDescription ?? "Unknown error")")
completionHandler(nil)
我应该怎么做才能确保打印 TOTAL2 的结果与 TOTAL1 相同。事实上,我需要在闭包之外使用数组 SAmple,但我不明白该怎么做。
如果您能帮助我,非常感谢 :-) 干杯
【问题讨论】:
在调用闭包之前你不能对数据做任何事情,但是如果不知道你将如何使用它,很难说什么解决方案适合你。 this question有一些建议 非常感谢乔金。多亏了你,我才能解决这个问题,我还发现了一个有用的链接:appcoda.com/swift-delegate 【参考方案1】:这个转义闭包将在未来某个时间执行,而不是绝对在print("TOTAL2:\(samples)")
之后执行。解决方案之一是将样本保存为视图属性并将其存储在您正在打印print("TOTAL1:\(samples)")
的闭包中。然后你可以稍后使用它。但问题是如何知道是否调用了闭包以及samples
是否有最新数据。
或者更好的是,您可以从第一个闭包中调用需要samples
的函数。确保使用weak self
。
【讨论】:
以上是关于如何在 Swift 中关闭和完成处理程序后获取数据的主要内容,如果未能解决你的问题,请参考以下文章
当我在谷歌设置android中关闭和打开位置时,FusedLocation 不起作用