From fe8ef21659c14b9b34fa8fdf0dd999f3bab99b44 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Thu, 8 Apr 2021 20:51:39 +0200 Subject: [PATCH] Fix memory leak in [RecentsDataSource dataSource:didStateChange:] The block passed into `[MXSession listenToEventsOfTypes:onEvent:]` is stored with a strong reference in the `listenerBlock` property of `MXSessionEventListener`. The method also returns the listener and it is then stored into the `roomTagsListenerByUserId` dictionary on `self`. Since a strong reference to `self` is captured in the block that means the block retains `self` (via the capture) and `self` retains the block (via `roomTagsListenerByUserId`) so there is a memory leak. The bug is most easily reproduced during testing #4168 which involves closing the current and creating a new session. Signed-off-by: Johannes Marbach --- CHANGES.rst | 1 + Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m | 3 +++ 2 files changed, 4 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 76bb579d0..363aaaa66 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -23,6 +23,7 @@ Changes to be released in next version * Black theme uses dark background for composer (#4192) * Vertical layout of typing notifs can go wonky (#4159) * Crash in [RoomViewController refreshTypingNotification] (#4161) + * Memory leak in [RecentsDataSource dataSource:didStateChange:] ⚠️ API Changes * diff --git a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m index 497f80fce..09989ec36 100644 --- a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m +++ b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m @@ -337,9 +337,12 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou if ((aState == MXKDataSourceStateReady) && dataSource.mxSession.myUser.userId) { // Register the room tags updates to refresh the favorites order + MXWeakify(self); id roomTagsListener = [dataSource.mxSession listenToEventsOfTypes:@[kMXEventTypeStringRoomTag] onEvent:^(MXEvent *event, MXTimelineDirection direction, id customObject) { + MXStrongifyAndReturnIfNil(self); + // Consider only live event if (direction == MXTimelineDirectionForwards) {