快速表格视图,在表格视图单元格中播放视频,内存泄漏

时间:2019-08-14 19:32:43

标签: swift firebase video memory-leaks avkit

我正在制作一个iOS应用程序,可以将其与instagram进行比较,并提供视频摘要(无图像)。我有一个显示自定义表格视图单元格的表格,每个表格视图单元格都包含一个使用AVKit播放的视频。目前,我有6个单元正在加载,并且正在使用令人难以置信的内存量来显示它们。像facebook,instagram或vine这样的应用程序如何在不使用大量内存的情况下显示这么多视频?

下面是我当前正在使用的代码。

var cells: [VideoCell] = []
    var cellPostkeys: [String] = []

    @IBOutlet weak var feedTableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        feedTableView.delegate = self
        feedTableView.dataSource = self
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 250
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return videoURLs.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let url = videoURLs[indexPath.row]
        if let cell = tableView.dequeueReusableCell(withIdentifier: "testcell") as? VideoCell {
            if (cellPostkeys.contains(url)) {
                let index = cellPostkeys.firstIndex(of: url)
                cells[index!] = cell
            } else {
                cells.append(cell)
                cellPostkeys.append(url)
            }
            cell.playvid(url: url)
            return cell
        } else {
            return VideoCell()
        }
    }
}

这是我的自定义表格视图单元格的代码

class VideoCell: UITableViewCell {

    @IBOutlet weak var videoView: UIView!


    var player : AVPlayer!
    var avPlayerLayer : AVPlayerLayer!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        //
    }

    func stopvid() {
        self.player = nil
        self.avPlayerLayer = nil
    }

    func playvid(url: String) {
        self.player = AVPlayer(url: URL(string: url)!)
        self.avPlayerLayer = AVPlayerLayer(player: self.player)
        self.avPlayerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
        self.player.automaticallyWaitsToMinimizeStalling = false
        avPlayerLayer.frame = videoView.layer.bounds;
        self.videoView.layer.addSublayer(self.avPlayerLayer)

        self.player.play()

        NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.player.currentItem, queue: .main) { [weak self] _ in
            self?.player?.seek(to: CMTime.zero)
            self?.player?.play()
        }
    }

}

我了解到,一次加载和播放6个视频显然会极大地增加内存消耗,因此我尝试仅播放1个视频,而其他5个单元却都空了,但是一旦我使用了大约100 mb以上的内存开始上下滚动。任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:0)

尝试在Xcode中使用Memory Debugger。检查是否有任何类似乎只会增加数量。可能是因为每次创建一个新的AVPlayer而从未停止前一个AVPlayer导致泄漏。

您不必每次都实例化AVPlayer。

private lazy var player: AVPlayer = AVPlayer(playerItem: nil)

private lazy var playerLayer: AVPlayerLayer = {
    let playerLayer = AVPlayerLayer(player: self.player)
    playerLayer.videoGravity = .resizeAspectFill
    return playerLayer
}()

override func awakeFromNib() {
    super.awakeFromNib()
    self.videoView.layer.addSublayer(self.playerLayer)
}

override func layoutSubviews() {
    super.layoutSubviews()
    avPlayerLayer.frame = videoView.layer.bounds
}

现在在stopvid()中,您可以暂停或致电player.replaceCurrentItem(with: nil)

playvid(url: String)中,您使用类似以下内容:

let playerItem = AVPlayerItem(url: URL(string: url)!)
player.placeCurrentItem(with: playerItem)
player.play()

请注意,由于我现在在Windows计算机上,因此我无法运行此代码,但是根据文档,它应该可以工作。