Tái sử dụng cell với dequeueReusableCellWithIdentifier:

8
Trần Duy Hưng viết hơn 1 năm trước

Trong lập trình iOS phải thường xuyên sử dụng các loại ScrollView như TableView, CollectionView. Chúng cho phép load các cell từ storyboard và sử dụng cell qua việc implement phương thức tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell đối với Tableview và collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell đối với CollectionView.

dequeueReusableCellWithIdentifier:

dequeueReusableCellWithIdentifier trả về một đối tượng table-view cell được định vị bởi identify của nó. Khi muốn reuse
cell trong tableview ta sử dụng tableView.dequeueReusableCell<Identifier: ReuseIdentifierType>(withIdentifier identifier: Identifier, for indexPath: IndexPath) Khi đó tableView sẽ reuse các cell được gán định danh Identifier tránh việc phải sinh ra nhiều cell mới giúp tiết kiệm tài nguyên của máy.

So sánh

Chúng ta sẽ đi so sánh performance khi sử dụng reuse và không resuse cell. Với số lượng cell nhỏ thì sẽ không thành vấn đề nhưng thử với khoảng 1000 cell ta sẽ thấy rõ được sự khác biệt

Không reuse cell

Trước tiên tạo một custom cell là ResuseTableViewCell trắng chỉ chứa một UILabel.
Tạo 1000 cell mới có kiểu là ResuseTableViewCell qua hàm setupCell()

class BadTableViewController: UITableViewController {
    var cells = [ReuseTableViewCell]()

    override func viewDidLoad() {
        super.viewDidLoad()
        title = "Bad"
        tableView.estimatedRowHeight = 50
        setupCell()
    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return cells.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = cells[indexPath.row]
        cell.index.text = "\(indexPath.row)"
        return cell
    }

    func setupCell() {
        for _ in 0 ... 1000 {
            let cell = Bundle.main.loadNibNamed("ReuseTableViewCell", owner: self, options: nil)?[0] as! ReuseTableViewCell
            cells.append(cell)
        }
    }
}

Cùng xem lượng tài nguyên mà bị chiếm như thế nào nhé
alt text

Reuse cell

Khi sử Reuse cell trước tiên ta phải đăng kí cell đó với một định danh qua hàm
register(_ nib: UINib?, forCellReuseIdentifier identifier: String)

class ReuseCellTableViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        title = "Reuse"
        tableView.estimatedRowHeight = 50
        let nib = UINib(nibName: "ReuseTableViewCell", bundle: Bundle.main)
        tableView.register(nib, forCellReuseIdentifier: "reuseTableViewCell")
    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return 1000
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "reuseTableViewCell", for: indexPath) as! ReuseTableViewCell
        cell.index.text = "\(indexPath.row)"
        return cell
    }
}

Cùng xem kết quả khi load 1000 cell như thế nào nhé

alt text

Kết quả

Việc reuse cell giúp ta tiết kiệm rất nhiều tài nguyên và cải thiện performance cho ứng dụng khi mà hiện tại việc tiết kiệm tài nguyên và tăng performance cho ứng dụng trên mobile luôn là một thứ đau đầu.

Bình luận


White
{{ comment.user.name }}
Hay Bỏ hay
{{ comment.like_count}}
White

Trần Duy Hưng

29 bài viết.
0 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}

{{like_count}}

kipalog

{{ comment_count }}

Bình luận


White
{{userFollowed ? 'Following' : 'Follow'}}
29 bài viết.
0 người follow

 Đầu mục bài viết