본문 바로가기

iOS/STUDY

[iOS] reloadItems, reconfigureItems 차이점

우선 이 함수를 쓰게 된 이유를 말해보자면

 

개인 프로젝트에서 Diffable datasource를 사용하면서 snapshot도 함께 사용하게 되었습니다.

만들던 프로젝트는 Todo 앱으로 버튼 클릭 시 isDone 변수의 값에 따라 UI가 업데이트되어야 했는데,

바뀐 Todo에 대하여 snapshot을 업데이트해도 UI가 업데이트되지 않았습니다.

 

해서 cell registration을 이용해 datasource를 다시 만들어 apply 시켰더니 적용은 됐지만 애니메이션 적용은 얻을 수 없었습니다.

 

-> 사실 reloadItems, reconfigureItems 을 사용했어야 했는데 이제야 발견했고..

발견한 김에 두가지 함수에 대해 차이점을 정리해보려고 합니다.

 

 

우선 경험으로 얻은 차이점을 보고 자세하게 살펴보겠습니다.

ReloadItems

티스토리는 왜 사진을 가로로 같이 놔두면 이상해지는가

 

reconfigureItems

 

reloadItems는 자세히 보면 전체 cell이 다시 불려와지는 것을 알 수 있고 (cell의 구분선이 다시 그려짐),

reconfigureItems는 모든 cell에 대해서 업데이트하는 것으로 보입니다.

 

에? 똑같은데.. ㅎ

공식문서를 봅시다.

 

 

 

reloadItems(_:)

Reloads the data within the specified items in the snapshot.
스냅샷에서 지정한 item의 데이터를 다시 로드합니다.
mutating func reloadItems(_ identifiers: [ItemIdentifierType])

reconfigureItems와 다른 점은 기존 셀을 유지하는 것이 아니라 다시 로드한다는 것입니다.

 

그렇다면 위에서 전체 cell을 다시 불러온다는 것은 알았는데 애니메이션 효과가 왜 그대로인지는 모르겠네요..

 

reconfigureItems(_:)

Updates the data for the items you specify in the snapshot, preserving the existing cells for the items.
item에 대한 기존 셀을 유지하면서 스냅샷에서 지정한 item에 대한 데이터를 업데이트합니다.
mutating func reconfigureItems(_ identifiers: [ItemIdentifierType])

사용하는 방법은 item의 식별자 배열을 넣으면 지정한 식별자에 대한 item의 데이터를 업데이트하는 것입니다.

 

이 설명대로라면 저는 모든 todo에 대한 식별자를 넘겨주었기 때문에 모든 todo의 데이터가 업데이트돼서 적용된 것으로 보입니다.

func updateSnapshot() {
    var snapshot = Snapshot()
    snapshot.appendSections(repositories.map { $0.id })

    for repository in repositories {
        snapshot.appendItems(Array(repository.todos.map { $0.id }), toSection: repository.id)
    }
    snapshot.reconfigureItems(todos.map{ $0.id })

    dataSource.apply(snapshot)
}

 

 

애플에서는 새로운 cell로 교체하지 않고 기존 cell의 내용을 업데이트 하려면 reconfigureItems()를 사용하라고 합니다.

기존의 cell을 새로운 셀로 교체해야할 필요가 없는 한 item을 다시 로드하는 대신 재구성하는 것이 성능이 더 좋다고 합니다.

 

reconfigureItems()는 기존 cell을 재구성하기 때문에 컬렉션 뷰 또는 테이블 뷰의 대기열에서 제거된 각 cell에 대해 prepareForReuse()라는 함수를 호출하지 않기때문입니다.

 

대신 indexPath에 대해 다른 타입의 cell을 반환해야 하는 경우에는 reloadItems()를 사용하라고 하고 있습니다.

 

cell이 크기가 조정되는 경우 컬렉션뷰 또는 테이블뷰는 cell을 재구성한 후 (configure) cell의 크기를 조정합니다.

 

결론은!

컬렉션뷰나 테이블뷰에서 diffable datasource를 사용하는 경우 reconfigureItems()를 사용해라

입니다

 

 

 

 

그래서 변경한 cell만 업데이트하도록 id를 받아 처리하게 코드를 바꿔보았습니다.

func updateSnapshot(with id: Todo.ID) {
    getRepositories()
    getTodos()

    var snapshot = Snapshot()
    snapshot.appendSections(repositories.map { $0.id })

    for repository in repositories {
        snapshot.appendItems(Array(repository.todos.map { $0.id }), toSection: repository.id)
    }
    snapshot.reconfigureItems([id])

    dataSource.apply(snapshot)
}

 

 

 

https://developer.apple.com/documentation/uikit/nsdiffabledatasourcesnapshot/3804468-reconfigureitems

 

Apple Developer Documentation

 

developer.apple.com