在Swift中关闭和完成处理程序后如何获取数据

问题描述

我是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)
    }
}

我应该怎么做才能得到与TOTAL1相同结果的Print TOTAL2。实际上,我需要在闭包外部使用数组SAmple,但我不知道该怎么做。

如果您能帮助我,我会非常感谢:-) 干杯

解决方法

此转义的闭包将在将来的某个时间执行,而不一定在print("TOTAL2:\(samples)")之后执行。解决方案之一是将样本另存为view属性,并在要打印print("TOTAL1:\(samples)")的闭包中存储它。然后您可以稍后使用它。但是问题将是如何知道是否调用了闭包并且samples拥有最新数据。

更好的是,您可以从第一个闭包内调用需要samples的函数。确保使用weak self