Skip to content

Commit 1e35bca

Browse files
authored
Fix Throttler crash in ChatChannelViewModel.handleMessageAppear() (#1050)
1 parent dfcd961 commit 1e35bca

File tree

3 files changed

+31
-4
lines changed

3 files changed

+31
-4
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
88
- Expose `FilePickerView.init(fileURLs:)` [#1049](https://github.com/GetStream/stream-chat-swiftui/pull/1049)
99
- Add `MessageComposerViewModel.updateAddedAssets()` [#1049](https://github.com/GetStream/stream-chat-swiftui/pull/1049)
1010

11+
### 🐞 Fixed
12+
- Fix `Throttler` crash in `ChatChannelViewModel.handleMessageAppear()` [#1050](https://github.com/GetStream/stream-chat-swiftui/pull/1050)
13+
- Remove unnecessary channel query call when leaving the channel view in a mid-page [#1050](https://github.com/GetStream/stream-chat-swiftui/pull/1050)
14+
1115
# [4.92.0](https://github.com/GetStream/stream-chat-swiftui/releases/tag/4.92.0)
1216
_November 07, 2025_
1317

Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource {
5050
private var channelName = ""
5151
private var onlineIndicatorShown = false
5252
private var lastReadMessageId: String?
53-
var throttler = Throttler(interval: 3, broadcastLatestEvent: true)
53+
var throttler = Throttler(interval: 3, broadcastLatestEvent: true, queue: .main)
5454

5555
public var channelController: ChatChannelController
5656
public var messageController: ChatMessageController?
@@ -833,14 +833,12 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource {
833833
}
834834

835835
deinit {
836+
throttler.cancel()
836837
messageCachingUtils.clearCache()
837838
if messageController == nil {
838839
utils.channelControllerFactory.clearCurrentController()
839840
cleanupAudioPlayer()
840841
ImageCache.shared.trim(toCost: utils.messageListConfig.cacheSizeOnChatDismiss)
841-
if !channelDataSource.hasLoadedAllNextMessages {
842-
channelDataSource.loadFirstPage { _ in }
843-
}
844842
}
845843
}
846844
}

StreamChatSwiftUITests/Tests/ChatChannel/ChatChannelViewModel_Tests.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,31 @@ class ChatChannelViewModel_Tests: StreamChatTestCase {
772772
XCTAssertEqual(0, channelController.markReadCallCount)
773773
}
774774

775+
func test_chatChannelVM_handleMessageAppear_doesNotCrashWhenDeallocated() {
776+
let message = ChatMessage.mock()
777+
let channelController = makeChannelController(messages: [message])
778+
channelController.hasLoadedAllNextMessages_mock = nil
779+
channelController.channel_mock = .mock(
780+
cid: .unique,
781+
unreadCount: ChannelUnreadCount(messages: 1, mentions: 0)
782+
)
783+
784+
for _ in 0..<1000 {
785+
autoreleasepool {
786+
let viewModel = ChatChannelViewModel(channelController: channelController)
787+
viewModel.handleMessageAppear(index: 0, scrollDirection: .down)
788+
viewModel.handleMessageAppear(index: 0, scrollDirection: .down)
789+
viewModel.handleMessageAppear(index: 0, scrollDirection: .down)
790+
viewModel.handleMessageAppear(index: 0, scrollDirection: .down)
791+
viewModel.handleMessageAppear(index: 0, scrollDirection: .down)
792+
viewModel.handleMessageAppear(index: 0, scrollDirection: .down)
793+
}
794+
}
795+
796+
// Then - Should not crash
797+
XCTAssert(true)
798+
}
799+
775800
// MARK: - highlightMessage Tests
776801

777802
func test_highlightMessage_highlightsWhenSkipHighlightMessageIdIsNotSet() {

0 commit comments

Comments
 (0)