History

Fix: suppress didSet observer during incremental token merge

In mergeTokensByRowId, each tokensByRowId[rowId] = tokens assignment triggered the didSet observer (Swift Dictionary is a value type), causing tokenAttributedStringsByRowId.removeAll(), clampHorizontalOffsets(), and setNeedsDisplayForVisibleBounds() to fire N times — once per patched row. This defeated the incremental cache invalidation the method intended and multiplied layout work for large token patches. Add a _suppressTokensByRowIdDidSet flag so the didSet observer is skipped during the merge loop. The method already performs its own targeted cache invalidation (removeValue per row) and calls clampHorizontalOffsets() and setNeedsDisplayForVisibleBounds() once at the end.

Cursor Agent committed 6 months ago

Commit e72d3641 parent 9b9fe0d1 file · +4 −0Browse files

Unified · Split

apps/mobile/modules/t3-review-diff/ios/T3ReviewDiffView.swift+4−0
@@ -689,8 +689,10 @@ private final class ReviewDiffContentView: UIView, UIGestureRecognizerDelegate { · 688 unmodified lines
689 setNeedsDisplayForVisibleBounds()689 setNeedsDisplayForVisibleBounds()
690 }690 }
691 }691 }
692 private var _suppressTokensByRowIdDidSet = false
692 var tokensByRowId: [String: [ReviewDiffNativeToken]] = [:] {693 var tokensByRowId: [String: [ReviewDiffNativeToken]] = [:] {
693 didSet {694 didSet {
695 guard !_suppressTokensByRowIdDidSet else { return }
694 tokenAttributedStringsByRowId.removeAll()696 tokenAttributedStringsByRowId.removeAll()
695 clampHorizontalOffsets()697 clampHorizontalOffsets()
696 setNeedsDisplayForVisibleBounds()698 setNeedsDisplayForVisibleBounds()
@@ -698,10 +700,12 @@ private final class ReviewDiffContentView: UIView, UIGestureRecognizerDelegate { · 1 unmodified line
698 }700 }
699 701
700 func mergeTokensByRowId(_ tokensPatch: [String: [ReviewDiffNativeToken]]) {702 func mergeTokensByRowId(_ tokensPatch: [String: [ReviewDiffNativeToken]]) {
703 _suppressTokensByRowIdDidSet = true
701 tokensPatch.forEach { rowId, tokens in704 tokensPatch.forEach { rowId, tokens in
702 tokensByRowId[rowId] = tokens705 tokensByRowId[rowId] = tokens
703 tokenAttributedStringsByRowId.removeValue(forKey: rowId)706 tokenAttributedStringsByRowId.removeValue(forKey: rowId)
704 }707 }
708 _suppressTokensByRowIdDidSet = false
705 clampHorizontalOffsets()709 clampHorizontalOffsets()
706 setNeedsDisplayForVisibleBounds()710 setNeedsDisplayForVisibleBounds()
707 }711 }