簡體   English   中英

Swift:來自調試器的消息:由於內存問題而終止

[英]Swift: Message from debugger: Terminated due to memory issue

這個問題與來自調試器的Ios Xcode消息中的問題不同:由於內存問題而終止 我正在使用其他設備,並且我的應用程序在前台被殺死,此外,我無法使用樂器查看分配。

我正在嘗試將許多AVAsets的短間隔合並到一個視頻文件中。 我需要在其上應用其他過濾器和轉換。

我實現了一些類,這些類可以使用一項資產,並完全按照我的意願進行操作,但是現在,當我嘗試使用許多資產(cca 7 aasets仍然可以做)做同樣的事情時,資產較短(完整持續時間可能會比使用一個資產短)資產),應用程序崩潰,並且我僅收到“來自調試器的消息:由於內存問題而終止”日志。

我無法使用大多數樂器工具,因為應用程序會立即崩潰。 我嘗試了很多方法來解決它,但未成功,我將非常感謝您的幫助。

謝謝

相關代碼段在這里:

創作作品:

func export(toURL url: URL, callback: @escaping (_ url: URL?) -> Void){
    var lastTime = kCMTimeZero
    var instructions : [VideoFilterCompositionInstruction] = []
    let composition = AVMutableComposition()
    composition.naturalSize = CGSize(width: 1080, height: 1920)

    for (index, assetURL) in assets.enumerated() {
        let asset : AVURLAsset? = AVURLAsset(url: assetURL)
        guard let track: AVAssetTrack = asset!.tracks(withMediaType: AVMediaType.video).first else{callback(nil); return}

        let range = CMTimeRange(start: CMTime(seconds: ranges[index].lowerBound, preferredTimescale: 1000),
                                end: CMTime(seconds: ranges[index].upperBound, preferredTimescale: 1000))

        let videoTrack = composition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: kCMPersistentTrackID_Invalid)!
        let audioTrack = composition.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: kCMPersistentTrackID_Invalid)!

        do{try videoTrack.insertTimeRange(range, of: track, at: lastTime)}
        catch _{callback(nil); return}

        if let audio = asset!.tracks(withMediaType: AVMediaType.audio).first{
            do{try audioTrack.insertTimeRange(range, of: audio, at: lastTime)}
            catch _{callback(nil); return}
        }

        let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)
        layerInstruction.trackID = videoTrack.trackID

        let instruction = VideoFilterCompositionInstruction(trackID: videoTrack.trackID,
                                                            filters: self.filters,
                                                            context: self.context,
                                                            preferredTransform: track.preferredTransform,
                                                            rotate : false)
        instruction.timeRange = CMTimeRange(start: lastTime, duration: range.duration)
        instruction.layerInstructions = [layerInstruction]

        instructions.append(instruction)

        lastTime = lastTime + range.duration
    }

    let videoComposition = AVMutableVideoComposition()
    videoComposition.customVideoCompositorClass = VideoFilterCompositor.self
    videoComposition.frameDuration = CMTimeMake(1, 30)
    videoComposition.renderSize = CGSize(width: 1080, height: 1920)
    videoComposition.instructions = instructions

    let session: AVAssetExportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality)!
    session.videoComposition = videoComposition
    session.outputURL = url
    session.outputFileType = AVFileType.mp4

    session.exportAsynchronously(){
        DispatchQueue.main.async{
            callback(url)
        }
    }

和AVVideoCompositing類的一部分:

func startRequest(_ request: AVAsynchronousVideoCompositionRequest){
    autoreleasepool() {
        self.getDispatchQueue().sync{
            guard let instruction = request.videoCompositionInstruction as? VideoFilterCompositionInstruction else{
                request.finish(with: NSError(domain: "jojodmo.com", code: 760, userInfo: nil))
                return
            }
            guard let pixels = request.sourceFrame(byTrackID: instruction.trackID) else{
                request.finish(with: NSError(domain: "jojodmo.com", code: 761, userInfo: nil))
                return
            }

            var image : CIImage? = CIImage(cvPixelBuffer: pixels)

            for filter in instruction.filters{
                filter.setValue(image, forKey: kCIInputImageKey)
                image = filter.outputImage ?? image
            }

            let newBuffer: CVPixelBuffer? = self.renderContext.newPixelBuffer()

            if let buffer = newBuffer{
                instruction.context.render(image!, to: buffer)
                request.finish(withComposedVideoFrame: buffer)
            }
            else{
                request.finish(withComposedVideoFrame: pixels)
            }
        }
    }

App返回內存警告時有一些規避措施。 這是由於我們試圖處理大量數據而引起的。

為了避免這種記憶警告,我們必須養成使用[unowned self]成績單的習慣。

如果我們沒有在關閉時使用此[unowned self] ,那么我們將收到內存泄漏警告,並且在某個階段,應用程序將崩潰。

您可以從下面的鏈接中找到[unowned self]更多信息: 我們應該在Swift的閉包內部始終使用[unown self]嗎?

添加[unowned self] deinit(){ } [unowned self] ,在您的類中添加deinit(){ }函數,並釋放或deinit(){ }不需要的數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM