0.4.2
Performance
Two more NSOutlineViewDiffableDataSource.applySnapshot costs are gone, both in the step that
translates a diff into NSOutlineView calls.
Reorders moved almost every row. The batch engine walked the target order and moved whatever was
not at its index. One row moved from far away therefore cost a move for every row it pushed along, and
each move searched the row model linearly: swapping a tenth of a thousand roots issued 989 moves for
184 rows that had actually changed place. The engine now keeps the longest run of rows already in
relative order, moves or inserts every other row exactly once, and derives every index arithmetically
instead of searching. Moves are still moves — row views, selection and expansion state travel with the
row as before — and a moved row lands at the index the snapshot gives it whichever direction it travels.
Expanding many parents settled the view once per parent. Expansion-state sync called
expandItem: / collapseItem: one at a time, and NSOutlineView settles its visible row views after
each call. They now share one beginUpdates / endUpdates, opened with the first call that needs it.
Measured against 0.4.1 on the same machine at the same time (release build, 1000 roots with five
collapsed children each, window on screen):
| 0.4.1 | 0.4.2 | UICollectionViewDiffableDataSource |
|
|---|---|---|---|
| swap 10% of the roots | 12.2 ms | 4.7 ms | 3.7 ms |
| reverse all roots | 19.0 ms | 12.9 ms | 12.4 ms |
| expand 100 roots | 15.1 ms | 6.4 ms | 7.5 ms |
| append 100 roots | 2.1 ms | 2.1 ms | 2.0 ms |
Appends, deletes, sectioned snapshots and fully expanded deep trees are unchanged.
One caveat for anyone benchmarking: after a batched expansion the view holds exactly the on-screen row
views, whereas one-by-one expansion used to leave about a dozen extra ones behind. A collapse measured
immediately after an expand therefore creates those views itself and reads one or two milliseconds
slower than before; from a view the user expanded, collapsing costs what it did.
Compatibility
Everything here is internal. No public API was added, removed or renamed, no type layout moved, and
the export table is unchanged — existing binaries keep working without recompiling.
Warning
AppKitPlus is in testing. No API or ABI stability is promised.
Any release may remove classes, change type layouts, or change protocol requirements, with no
deprecation period. Pin an exact version and read these notes before upgrading.
Installation
.package(url: "https://github.com/AppKitSupportProgram/AppKitPlus-Release", from: "0.4.2")Artifact
| Platform | macOS 12.0+ |
| Architectures | arm64, arm64e, x86_64 |
| Built with | Xcode 26.6 Build version 17F113 |
| SHA-256 | 995651eaa2a61c18dc5682f6952e9adfb7df82a35490d8b67cb29e915f161d1e |