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

Posted

技术标签:

【中文标题】Swift 表格视图,在表格视图单元格中播放视频,内存泄漏【英文标题】:Swift table view with videos playing in table view cells, memory leak 【发布时间】:2019-08-14 19:32:43 【问题描述】:

我正在制作一个 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 的内存。开始上下滚动。任何和所有的帮助将不胜感激。

【问题讨论】:

这个问题被标记为 Firebase,但我在问题中看不到任何与 Firebase 相关的内容。此外,还不清楚视频的存储位置、格式以及每个视频的大小(像素大小和实际 Mb 大小)。这可能是答案中的一个重要因素,所以你能用更多的细节更新这个问题吗? 【参考方案1】:

尝试在 Xcode 中使用内存调试器。检查是否有任何课程的数量似乎只会增加。它可能会泄漏,因为您每次都创建一个新的 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 机器上,所以我无法运行此代码,但根据文档,它应该可以工作。

【讨论】:

以上是关于Swift 表格视图,在表格视图单元格中播放视频,内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

在表格视图单元格中添加集合视图 swift 3

为啥两个表格视图单元格中的两个集合视图在 Swift 4 中不起作用?

以swift语言在自定义表格视图单元格中更新进度视图下载

如何在编辑表格视图单元格中的文本字段时重新加载所有表格视图单元格 - iOS Swift

iOS - 使用 Swift 在每个表格视图单元格中获取 JSON 提要

表格视图单元格中的圆形图像 swift