hariszaman
hariszaman

Reputation: 8424

Performance issue with tableView inside CollectionViewcell

I have a ViewController which has a collection view. Inside each collection view cell their is a tableview. And I am facing a performance issue because of that tableView. I try to reloadData for each of CollectionViewCell when its cellforItemAtIndexPath is called. My CPU usage gets uptp 90% because of that. My ViewController looks like this

func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
    return 1
}

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 10
}

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("MyCustomCollectionViewCell", forIndexPath: indexPath) as! MyCustomCollectionViewCell
        // This line is causing performance issue 
        cell.tableView.reloadData()
        return cell     

}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {

    return CGSizeMake(40, 40)
}

MyCustomCollectionViewCell looks like this

class ChannelCollectionViewCell: UICollectionViewCell, UITableViewDelegate, UITableViewDataSource, UIScrollViewDelegate {


    @IBOutlet weak var tableView: UITableView!
    var delegate: ChannelCollectionViewCellDelegate?


    // MARK: - Table view data source
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {

        return 10
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
       return 120
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
                let cell = tableView.dequeueReusableCellWithIdentifier("MyCustomTableViewCell", forIndexPath:
                    indexPath) as! MyCustomTableViewCell
                cell.title = "Testt Title"
                return cell
    }

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    }

    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return 50
    }
}

Can cell.tableView.reloadData() be moved to a better place so that it doesn't cause performance issues

Upvotes: 1

Views: 658

Answers (1)

farzadshbfn
farzadshbfn

Reputation: 2748

I don't think so, because UITableView like UICollectoinView fill themselves with dataSource, and when you dequeue another UICollectoinViewCell you have to call reloadData() (because this cell might be initialized before and you have to refill it).

What you can do is to stop dequeuing (do it at your own risks). Dequeuing is a technique for memory optimization, If you have only 10 cells in collectionView, you "can" init a UICollectionViewCell directly and show it. But collectionView will still call cellForRowAtIndexPath so you have to cache all cells for each indexPaths, if you have already initialized the cell, return it. But this technique uses lots of memory, so it's probable you receive lots of memory warnings.

I guess you're implementing something like Trello or something (because tableView in collectionView which tableView contains about 120 rows does not sound logical to me :/). If that's the case i suggest change your architecture to UIPageViewController + UITableViewContoller.

Upvotes: 1

Related Questions