tvOS应用程序内存问题:如何解决它?

问题描述:

我有有一个视频在它玩tvOS应用。 基本上有两种视频(同一视频的不同速度的版本)。一个是12MB大小,另一个是1.9MB。tvOS应用程序内存问题:如何解决它?

当应用程序启动时,它运行良好(Xcode中示出了191MB)。但是,当点击正常速度按钮一次,内存就会达到350MB。当我分别点击普通按钮和快速按钮时,这种情况会持续增加,并且一度变为1GB +。你可以看到附件。当视频结束并且应用程序停止时,它甚至达到了3GB。 enter image description here

有没有办法从停止解决内存问题并保存应用程序?

的另一个问题是:当苹果电视,我们去到另一个应用程序从这个程序,并回来,视频再次停止。但是,在模拟器中,它不会发生。有人可以帮我解决这两个问题吗?

这里是我使用的代码:

var avPlayerLayer: AVPlayerLayer! 
var paused: Bool = false 

func playmyVideo(myString: String) { 

    let bundle: Bundle = Bundle.main 
    let videoPlayer: String = bundle.path(forResource: myString, ofType: "mov")! 
    let movieUrl : NSURL = NSURL.fileURL(withPath: videoPlayer) as NSURL 

    print(movieUrl) 

    viewVideo.playVideoWithURL(url: movieUrl) 


} 
@IBAction func normalPressed(_ sender: Any) { 

    playmyVideo(myString: "normal") 


} 


@IBAction func forwardPressed(_ sender: Any) { 

    playmyVideo(myString: "fast") 

} 

class VideoPlay: UIView { 


private var player : AVPlayer! 

private var playerLayer : AVPlayerLayer! 

init() { 

    super.init(frame: CGRect.zero) 
    self.initializePlayerLayer() 

} 

override init(frame: CGRect) { 
    super.init(frame: frame) 
    self.initializePlayerLayer() 
    self.autoresizesSubviews = false 
} 

required init?(coder aDecoder: NSCoder) { 
    super.init(coder: aDecoder) 
    self.initializePlayerLayer() 

} 



private func initializePlayerLayer() { 

    playerLayer = AVPlayerLayer() 
    playerLayer.backgroundColor = UIColor.clear.cgColor 



    playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill 


    self.layer.addSublayer(playerLayer) 

    playerLayer.frame = UIScreen.main.bounds 


} 

func playVideoWithURL(url: NSURL) { 

    player = AVPlayer(url: url as URL) 
    player.isMuted = false 

    playerLayer.player = player 

    player.play() 

    loopVideo(videoPlayer: player) 
} 

func toggleMute() { 
    player.isMuted = !player.isMuted 
} 

func isMuted() -> Bool 
{ 
    return player.isMuted 
} 

func loopVideo(videoPlayer: AVPlayer) { 

    NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil, queue: nil) { notification in 
     let t1 = CMTimeMake(5, 100); 
     self.player.seek(to: t1) 
     videoPlayer.seek(to: kCMTimeZero) 
     self.player.play() 
    } 
} 

} 
+0

和一些代码你在用什么? –

+0

@SamuelTulach嗨。我已经包含了我们正在使用的代码 – BizDev

+0

@SamuelTulach HI。请检查我的代码... – BizDev

我看到你的代码的两个问题:

  1. 每次playVideoWithURL方法被调用,你创建的,而不是已经重用新AVPlayer例如,现有的。当你要玩另一个URL你可以叫你的player财产replaceCurrentItem(with:)方法。

这本身是有点低效率的,但应该不会造成你所说的内存问题。我认为原因是:

  1. 每次调用loopVideo方法时,都会传递一个闭包给NotificationCenter.default.addObserver。此封闭对videoPlayer产生了强烈的参考。你永远不会从通知中心删除观察者。

由于loopVideo在每次创建新AVPlayer实例时调用,这些实例都永远不会释放,从而导致您所描述的内存问题。

要解决它,你可以:

  • 初始化player酒店只有playVideoWithURL一次,然后用replaceCurrentItem当你要玩另一个视频
  • 也改变了“循环”的逻辑,让你打电话NotificationCenter.default.addObserver只有一次
  • 您传递给NotificationCenter.default.addObserver的关闭会造成内存泄漏(请参阅this question)。您可以通过捕获self弱摆脱它:

    NotificationCenter.default.addObserver(forName:
    NSNotification.Name.AVPlayerItemDidPlayToEndTime,object: nil, queue: nil) { [weak self], notification in

    self?.player.seek(to: kCMTimeZero) 
        self?.player.play() 
    

    }

还记得打电话removeObserverVideoPlay类的deinit方法。