Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Collection Update

Khoa Pham
November 27, 2017

Collection Update

Demo how UITableView, UICollection performs batch update

Khoa Pham

November 27, 2017
Tweet

More Decks by Khoa Pham

Other Decks in Programming

Transcript

  1. Collection Update

    View full-size slide

  2. About
    [email protected]
    —https://github.com/onmyway133
    —https://github.com/hyperoslo

    View full-size slide

  3. Content
    —TableView / CollectionView
    —Drag and Drop
    —Let's play some games
    !
    —Diff

    View full-size slide

  4. NSCollectionView
    !

    View full-size slide

  5. Drag and Drop
    Demo
    !

    View full-size slide

  6. index vs offset
    Array(0..<10).enumerated().forEach { (offset, element) in
    }
    - https://en.wikipedia.org/wiki/Zero-based_numbering
    - offset from the starting position

    View full-size slide

  7. NSInternalInconsistencyException
    Terminating app due to uncaught exception 'NSInternalInconsistencyException',
    reason: 'Invalid update: invalid number of items in section 0.
    The number of items contained in an existing section after the update (213)
    must be equal to the number of items contained in that section before
    the update (154), plus or minus the number of items inserted or
    deleted from that section (40 inserted, 0 deleted) and plus
    or minus the number of items moved into or out of
    that section (0 moved in, 0 moved out).'

    View full-size slide

  8. Game of IndexPath
    —https://github.com/onmyway133/
    CollectionUpdateExample
    —10 quizzes
    items = ["a", "b", "c", "d", "e", "f"]

    View full-size slide

  9. 1) insert 3 items at the end
    items.append(contentsOf: ["g", "h", "i"])
    // a, b, c, d, e, f, g, h, i
    let indexPaths = Array(6...8).map { IndexPath(item: $0, section: 0) }
    collectionView.insertItems(at: indexPaths)

    View full-size slide

  10. 2) delete 3 items at the end
    items.removeLast()
    items.removeLast()
    items.removeLast()
    // a, b, c
    let indexPaths = Array(3...5).map { IndexPath(item: $0, section: 0) }
    collectionView.deleteItems(at: indexPaths)

    View full-size slide

  11. 3) update item at index 2
    items[2] = "
    !
    "
    // a, b,
    !
    , d, e, f
    let indexPath = IndexPath(item: 2, section: 0)
    collectionView.reloadItems(at: [indexPath])

    View full-size slide

  12. 4) move item "c" to the end
    items.remove(at: 2)
    items.append("c")
    // a, b, d, e, f, c
    collectionView.moveItem(
    at: IndexPath(item: 2, section: 0),
    to: IndexPath(item: 5, section :0)
    )

    View full-size slide

  13. 5) delete 3 items at the beginning, then insert 3
    items at the end
    items.removeFirst()
    items.removeFirst()
    items.removeFirst()
    items.append(contentsOf: ["g", "h", "i"])
    // d, e, f, g, h, i
    collectionView.performBatchUpdates({
    let deleteIndexPaths = Array(0...2).map { IndexPath(item: $0, section: 0) }
    collectionView.deleteItems(at: deleteIndexPaths)
    let insertIndexPaths = Array(3...5).map { IndexPath(item: $0, section: 0) }
    collectionView.insertItems(at: insertIndexPaths)
    }, completion: nil)

    View full-size slide

  14. 6) insert 3 items at the end, then delete 3 items
    beginning
    items.append(contentsOf: ["g", "h", "i"])
    items.removeFirst()
    items.removeFirst()
    items.removeFirst()
    // d, e, f, g, h, i
    collectionView.performBatchUpdates({
    let insertIndexPaths = Array(6...8).map { IndexPath(item: $0, section: 0) }
    collectionView.insertItems(at: insertIndexPaths)
    let deleteIndexPaths = Array(0...2).map { IndexPath(item: $0, section: 0) }
    collectionView.deleteItems(at: deleteIndexPaths)
    }, completion: nil)

    View full-size slide

  15. !
    Terminating app due to uncaught exception
    'NSInternalInconsistencyException',
    reason: 'attempt to insert item 6 into section 0,
    but there are only 6 items in section 0 after the update'

    View full-size slide

  16. performBatchUpdates
    Deletes are processed before inserts in batch
    operations

    View full-size slide

  17. 6) insert 3 items at the end, then delete 3 items
    beginning
    !
    items.append(contentsOf: ["g", "h", "i"])
    items.removeFirst()
    items.removeFirst()
    items.removeFirst()
    // d, e, f, g, h, i
    collectionView.performBatchUpdates({
    let deleteIndexPaths = Array(0...2).map { IndexPath(item: $0, section: 0) }
    collectionView.deleteItems(at: deleteIndexPaths)
    let insertIndexPaths = Array(3...5).map { IndexPath(item: $0, section: 0) }
    collectionView.insertItems(at: insertIndexPaths)
    }, completion: nil)

    View full-size slide

  18. Operations
    insertItems(at indexPaths: [IndexPath])
    deleteItems(at indexPaths: [IndexPath])
    reloadItems(at indexPaths: [IndexPath])
    moveItem(at indexPath: IndexPath, to newIndexPath: IndexPath)
    performBatchUpdates(_ updates, completion)
    insertSections(_ sections: IndexSet)
    deleteSections(_ sections: IndexSet)
    reloadSections(_ sections: IndexSet)
    moveSection(_ section: Int, toSection newSection: Int)

    View full-size slide

  19. Ordering of Operations and Index Paths
    —https://developer.apple.com/library/content/
    documentation/UserExperience/Conceptual/
    TableView_iPhone/ManageInsertDeleteRow/
    ManageInsertDeleteRow.html

    View full-size slide

  20. Wagner–Fischer algorithm
    —https://en.wikipedia.org/wiki/
    Wagner%E2%80%93Fischer_algorithm
    —https://en.wikipedia.org/wiki/
    Dynamic_programming
    Computes the edit distance between two strings of
    characters.

    View full-size slide

  21. "kit" -> "kat"

    View full-size slide

  22. Deletions
    "k" -> ""
    !
    1 deletion
    "ki" -> ""
    !
    2 deletions
    "kit" -> ""
    !
    3 deletions

    View full-size slide

  23. Insertions
    "" -> "k"
    !
    1 insertion
    "" -> "ka"
    !
    2 insertions
    "" -> "kat"
    !
    3 insertions

    View full-size slide

  24. If equal, take value from the top left

    View full-size slide

  25. horizonally: insertion
    vertically: deletion
    diagonally: substitution
    If not equal, check minimum value from left, top, top
    left. Then increase by one

    View full-size slide

  26. "k" -> "kat"
    !
    2 insertions

    View full-size slide

  27. It equals again, take value from top left.
    Bottom right value gives edit distance (number of
    steps)
    "kit" -> "kat"
    !
    Substitute "i" with "a"

    View full-size slide

  28. insertions: insertItems
    deletions: deleteItems
    substitutions: reloadItems
    move: deletion + insertion moveItem

    View full-size slide

  29. Edit steps
    —delete, insert, move, substitute
    —https://github.com/onmyway133/DeepDiff

    View full-size slide

  30. Complexity
    —O(mn)
    —10k items
    !
    Performance
    —Collection size
    —Equatable
    —Hashable

    View full-size slide

  31. Alternatives
    —Heckel http://documents.scribd.com/docs/
    10ro9oowpo1h81pgh1as.pdf
    —Wu https://publications.mpi-cbg.de/
    Wu19906334.pdf
    —Myers http://www.xmailserver.org/diff2.pdf

    View full-size slide

  32. Q & A
    Thanks for listening. Hope you have a great time

    View full-size slide