ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • iOS) TableView refresh - index out of range 오류
    iOS 2020. 8. 10. 12:03

    TableView를 refresh 하기 위한 방법은 너무나도 간단하다.
    UIRefreshControl 클래스의 객체 하나를 생성해서 tableView에 subView로 추가만 해주면 된다.

    lazy var refreshController: UIRefreshControl = {
            let refreshControl = UIRefreshControl()
            refreshControl.attributedTitle = NSAttributedString(string: "refresh")
            return refreshControl
        }()
        
    ...
        
    if #available(iOS 10.0, *) {
                newsTableView.refreshControl = refreshController
            } else {
                newsTableView.addSubview(refreshController)
            }
            refreshController.addTarget(self, action: #selector(refresh), for: .valueChanged)

    But.. 네트워크 통신을 이용한 데이터 모델을 사용할 때 갱신하는 경우 index 오류가 났다.

    @objc func refresh() {
            Model.newsData.removeAll()
            Parser.count = 0 // 로딩을 위한 수치
            fetchData()
        }

     

    refresh 마다 테이블뷰에서 뿌려주는 모델의 배열을 모두 삭제하고 다시 로딩한다.

    문제는 테이블뷰를 당겼다가 놓는 행위에서 테이블 뷰 재사용 때문에 이미 비워진 cell을 다시 return 해주는 것이다.
    이미 배열은 비워 졌지만 사라졌다가 나타난 cell의 데이터를 리턴해주기 때문에 index 오류가 나는 것.

     

    어떻게 해야 하나 하다가 정말 간단하게 해결해 버렸다.
    우선 tableVeiw가 갱신되기 전에 기존 모델의 배열을 temp 배열에 복사해준다.
    tableView에 뿌려지는 데이터는 복사된 temp 배열이다.
    refresh 할 때마다 기존 모델의 배열을 삭제시켜주고 다시 갱신되기 전에 temp 배열에 복사 후 뿌려준다.

    private func fetchData() {
          Parser.shared.parseFeed(url: self.url!)
          NotificationCenter.default.addObserver(forName: Parser.parsingNoti, object: nil, queue: .main) { (noti) in
                Model.tempData = Model.newsData // 요부분이 핵심
                self.newsTableView.reloadData()
                self.refreshController.endRefreshing()
          }
          activeIndicator()

     

    네트워크 통신이 수행되고 모델이 갱신될 동안에도 tableView 모델인 temp 배열에는 변화가 없다.
    모델이 완전히 갱신된 후 temp 모델을 갱신시켜준다.

    댓글

Designed by Tistory.