tvOS应用程序内存问题:如何解决它?
问题描述:
我有有一个视频在它玩tvOS应用。 基本上有两种视频(同一视频的不同速度的版本)。一个是12MB大小,另一个是1.9MB。tvOS应用程序内存问题:如何解决它?
当应用程序启动时,它运行良好(Xcode中示出了191MB)。但是,当点击正常速度按钮一次,内存就会达到350MB。当我分别点击普通按钮和快速按钮时,这种情况会持续增加,并且一度变为1GB +。你可以看到附件。当视频结束并且应用程序停止时,它甚至达到了3GB。
有没有办法从停止解决内存问题并保存应用程序?
的另一个问题是:当苹果电视,我们去到另一个应用程序从这个程序,并回来,视频再次停止。但是,在模拟器中,它不会发生。有人可以帮我解决这两个问题吗?
这里是我使用的代码:
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()
}
}
}
答
我看到你的代码的两个问题:
- 每次
playVideoWithURL
方法被调用,你创建的,而不是已经重用新AVPlayer
例如,现有的。当你要玩另一个URL你可以叫你的player
财产replaceCurrentItem(with:)方法。
这本身是有点低效率的,但应该不会造成你所说的内存问题。我认为原因是:
- 每次调用
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()
}
还记得打电话removeObserver
在VideoPlay
类的deinit
方法。
和一些代码你在用什么? –
@SamuelTulach嗨。我已经包含了我们正在使用的代码 – BizDev
@SamuelTulach HI。请检查我的代码... – BizDev