UIViewController里面CollectionViewCell的内存问题

时间:2018-10-26 14:24:12

标签: ios swift uiviewcontroller uicollectionview uicollectionviewcell

我正在UICollectionViewCell中显示UIViewController。每页一个单元格。问题是,当我滑动到下一页时,内存会不断增加,再也不会回来。

这是相关的代码。

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let newsVC: NewsTableVC = {
        return storyboard?.instantiateViewController(withIdentifier: "NewsListVC")
        }() as! NewsTableVC

    let cell = pagerCollectionView.dequeueReusableCell(withReuseIdentifier: "PageCollectionViewCell", for: indexPath) as! PageCollectionViewCell

    //Wraping ViewController in CollectionView Cell
    return wrapAndGetCell(viewColtroller: newsVC, cell: cell)

}

func wrapAndGetCell(viewColtroller: UIViewController, cell: PageCollectionViewCell) -> PageCollectionViewCell{
    //setting tag to remove view when it's being reused
    viewColtroller.view.tag = PageCollectionViewCell.SUBVIEW_TAG
    addChild(viewColtroller)
    viewColtroller.view.frame = cell.contentView.bounds
    cell.contentView.addSubview(viewColtroller.view)
    viewColtroller.didMove(toParent: self)
    return cell
}

这是collectionViewCell类

class PageCollectionViewCell: UICollectionViewCell {

    static let SUBVIEW_TAG: Int = 1000

    override func prepareForReuse(){
        super.prepareForReuse()
        let subViews = self.contentView.subviews
        for subView in subViews{
            if subView.tag == PageCollectionViewCell.SUBVIEW_TAG{
                subView.removeFromSuperview()
                print("subView removed")
            }
        }
    }
}

我想问题是在每个单元格中添加了子视图,但是我也用perpareForReuse()方法删除了子视图。

请帮助我确定问题所在。

2 个答案:

答案 0 :(得分:0)

问题在于,每次使单元出队时,您都在创建一个新的NewsTableVC。您要做的只是重复使用相同的视图控制器,而不是每次获取一个单元时都创建一个新的视图控制器。

创建类型为[NewsTableVC]的数组,然后执行以下操作:

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let newsVC = self.newsVCArray[indexPath.item]

    let cell = pagerCollectionView.dequeueReusableCell(withReuseIdentifier: "PageCollectionViewCell", for: indexPath) as! PageCollectionViewCell

    //Wraping ViewController in CollectionView Cell
    return wrapAndGetCell(viewColtroller: newsVC, cell: cell)

}

这应该可以解决您的内存问题,但是创建将viewController的视图添加为collectionViewCell子视图似乎很奇怪。除非您有很好的理由这样做,否则我建议您仅使用PageCollectionViewCell,而完全不用考虑NewsTableVC

我不知道您要完成什么,但是很难想象有这样一种场景可以使用collectionViewCell。

答案 1 :(得分:0)

我认为这是问题所在

addChild(viewColtroller)  //1
viewColtroller.view.frame = cell.contentView.bounds
cell.contentView.addSubview(viewColtroller.view)
viewColtroller.didMove(toParent: self)

(1 *)自身(UIViewController)强烈保留“子级” ViewController

当您准备单元格的ForeForReuse时,您只是从层次结构中删除了“ childViewController”视图,但UIViewController(父级)仍保留了“ childViewController”视图。

当您将一个新单元格出队时,您可以重复此过程,创建一个新的子级并将其添加到父级中,而不会删除前一个子级

viewController.removeFromParentViewController()

,因此不会释放孩子。随着每个单元出队(实际上每个新的childViewController添加到父单元),这将增加内存。

确认这一点的好方法是在“子级” viewcontroller deinit方法上放置一个断点。

  deinit {
// Breakpoint here
print("DEINIT")
}

注意:这里需要打印,空方法不会捕获断点。

此外,要调试它,可以在添加新子项之前打印出childViewControllers

print(self.childViewControllers)

因此,在简历中,这里的问题是cildViewControllers被“父”保留,并且您在每个出队中添加了新的。

希望获得帮助,对于回复的时间很长。