mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-05-06 16:07:42 +02:00
Merge pull request #5056 from vector-im/steve/5055_roomvc_retain_cycles
RoomVC: Retain cycles prevent RoomViewController to be deallocated
This commit is contained in:
@@ -50,13 +50,13 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
||||
NSIndexPath* lastPotentialCellPath;
|
||||
|
||||
// Observe UIApplicationDidEnterBackgroundNotification to cancel editing mode when app leaves the foreground state.
|
||||
id UIApplicationDidEnterBackgroundNotificationObserver;
|
||||
__weak id UIApplicationDidEnterBackgroundNotificationObserver;
|
||||
|
||||
// Observe kAppDelegateDidTapStatusBarNotification to handle tap on clock status bar.
|
||||
id kAppDelegateDidTapStatusBarNotificationObserver;
|
||||
__weak id kAppDelegateDidTapStatusBarNotificationObserver;
|
||||
|
||||
// Observe kMXNotificationCenterDidUpdateRules to update missed messages counts.
|
||||
id kMXNotificationCenterDidUpdateRulesObserver;
|
||||
__weak id kMXNotificationCenterDidUpdateRulesObserver;
|
||||
|
||||
MXHTTPOperation *currentRequest;
|
||||
|
||||
@@ -65,7 +65,7 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
||||
UISearchBar *tableSearchBar;
|
||||
|
||||
// Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change.
|
||||
id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
__weak id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
}
|
||||
|
||||
@property (nonatomic, strong) CreateRoomCoordinatorBridgePresenter *createRoomCoordinatorBridgePresenter;
|
||||
@@ -156,11 +156,15 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
||||
// Apply dragging settings
|
||||
self.enableDragging = _enableDragging;
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Observe UIApplicationDidEnterBackgroundNotification to refresh bubbles when app leaves the foreground state.
|
||||
UIApplicationDidEnterBackgroundNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
// Leave potential editing mode
|
||||
[self cancelEditionMode:isRefreshPending];
|
||||
[self cancelEditionMode:self->isRefreshPending];
|
||||
|
||||
}];
|
||||
|
||||
@@ -170,6 +174,8 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
||||
// Observe user interface theme change.
|
||||
kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self userInterfaceThemeDidChange];
|
||||
|
||||
}];
|
||||
@@ -268,9 +274,13 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
||||
[self.recentsTableView deselectRowAtIndexPath:indexPath animated:NO];
|
||||
}
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Observe kAppDelegateDidTapStatusBarNotificationObserver.
|
||||
kAppDelegateDidTapStatusBarNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kAppDelegateDidTapStatusBarNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self scrollToTop:YES];
|
||||
|
||||
}];
|
||||
@@ -278,6 +288,8 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro
|
||||
// Observe kMXNotificationCenterDidUpdateRules to refresh missed messages counts
|
||||
kMXNotificationCenterDidUpdateRulesObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXNotificationCenterDidUpdateRules object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self refreshRecentsTable];
|
||||
|
||||
}];
|
||||
|
||||
@@ -44,7 +44,7 @@ const CGFloat kTypingCellHeight = 24;
|
||||
// Timer used to debounce cells refresh
|
||||
@property (nonatomic, strong) NSTimer *refreshCellsTimer;
|
||||
|
||||
@property (nonatomic, readonly) id<RoomDataSourceDelegate> roomDataSourceDelegate;
|
||||
@property (nonatomic, weak, readonly) id<RoomDataSourceDelegate> roomDataSourceDelegate;
|
||||
|
||||
@property(nonatomic, readwrite) RoomEncryptionTrustLevel encryptionTrustLevel;
|
||||
|
||||
|
||||
@@ -77,6 +77,10 @@ final class RoomCoordinator: NSObject, RoomCoordinatorProtocol {
|
||||
|
||||
super.init()
|
||||
}
|
||||
|
||||
deinit {
|
||||
roomViewController.destroy()
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
@@ -90,7 +94,8 @@ final class RoomCoordinator: NSObject, RoomCoordinatorProtocol {
|
||||
self.roomViewController.delegate = self
|
||||
|
||||
// Detect when view controller has been dismissed by gesture when presented modally (not in full screen).
|
||||
self.roomViewController.presentationController?.delegate = self
|
||||
// FIXME: Find a better way to manage modal dismiss. This makes the `roomViewController` to never be released
|
||||
// self.roomViewController.presentationController?.delegate = self
|
||||
|
||||
if let eventId = self.selectedEventId {
|
||||
self.loadRoom(withId: self.parameters.roomId, and: eventId, completion: completion)
|
||||
|
||||
@@ -144,7 +144,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
||||
{
|
||||
|
||||
// The preview header
|
||||
PreviewRoomTitleView *previewHeader;
|
||||
__weak PreviewRoomTitleView *previewHeader;
|
||||
|
||||
// The customized room data source for Vector
|
||||
RoomDataSource *customizedRoomDataSource;
|
||||
@@ -156,7 +156,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
||||
NSArray *currentTypingUsers;
|
||||
|
||||
// Typing notifications listener.
|
||||
id typingNotifListener;
|
||||
__weak id typingNotifListener;
|
||||
|
||||
// The position of the first touch down event stored in case of scrolling when the expanded header is visible.
|
||||
CGPoint startScrollingPoint;
|
||||
@@ -168,33 +168,33 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
||||
UIView *missedDiscussionsDotView;
|
||||
|
||||
// Potential encryption details view.
|
||||
EncryptionInfoView *encryptionInfoView;
|
||||
__weak EncryptionInfoView *encryptionInfoView;
|
||||
|
||||
// The list of unknown devices that prevent outgoing messages from being sent
|
||||
MXUsersDevicesMap<MXDeviceInfo*> *unknownDevices;
|
||||
|
||||
// Observe kAppDelegateDidTapStatusBarNotification to handle tap on clock status bar.
|
||||
id kAppDelegateDidTapStatusBarNotificationObserver;
|
||||
__weak id kAppDelegateDidTapStatusBarNotificationObserver;
|
||||
|
||||
// Observe kAppDelegateNetworkStatusDidChangeNotification to handle network status change.
|
||||
id kAppDelegateNetworkStatusDidChangeNotificationObserver;
|
||||
__weak id kAppDelegateNetworkStatusDidChangeNotificationObserver;
|
||||
|
||||
// Observers to manage MXSession state (and sync errors)
|
||||
id kMXSessionStateDidChangeObserver;
|
||||
__weak id kMXSessionStateDidChangeObserver;
|
||||
|
||||
// Observers to manage ongoing conference call banner
|
||||
id kMXCallStateDidChangeObserver;
|
||||
id kMXCallManagerConferenceStartedObserver;
|
||||
id kMXCallManagerConferenceFinishedObserver;
|
||||
__weak id kMXCallStateDidChangeObserver;
|
||||
__weak id kMXCallManagerConferenceStartedObserver;
|
||||
__weak id kMXCallManagerConferenceFinishedObserver;
|
||||
|
||||
// Observers to manage widgets
|
||||
id kMXKWidgetManagerDidUpdateWidgetObserver;
|
||||
__weak id kMXKWidgetManagerDidUpdateWidgetObserver;
|
||||
|
||||
// Observer kMXRoomSummaryDidChangeNotification to keep updated the missed discussion count
|
||||
id mxRoomSummaryDidChangeObserver;
|
||||
__weak id mxRoomSummaryDidChangeObserver;
|
||||
|
||||
// Observer for removing the re-request explanation/waiting dialog
|
||||
id mxEventDidDecryptNotificationObserver;
|
||||
__weak id mxEventDidDecryptNotificationObserver;
|
||||
|
||||
// The table view cell in which the read marker is displayed (nil by default).
|
||||
MXKRoomBubbleTableViewCell *readMarkerTableViewCell;
|
||||
@@ -209,13 +209,13 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
||||
NSArray<UIBarButtonItem *> *rightBarButtonItems;
|
||||
|
||||
// Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change.
|
||||
id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
__weak id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
|
||||
// Observe URL preview updates to refresh cells.
|
||||
id URLPreviewDidUpdateNotificationObserver;
|
||||
__weak id URLPreviewDidUpdateNotificationObserver;
|
||||
|
||||
// Listener for `m.room.tombstone` event type
|
||||
id tombstoneEventNotificationsListener;
|
||||
__weak id tombstoneEventNotificationsListener;
|
||||
|
||||
// Homeserver notices
|
||||
MXServerNotices *serverNotices;
|
||||
@@ -454,9 +454,13 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
||||
|
||||
self.jumpToLastUnreadLabel.text = [VectorL10n roomJumpToFirstUnread];
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Observe user interface theme change.
|
||||
kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self userInterfaceThemeDidChange];
|
||||
|
||||
}];
|
||||
@@ -587,9 +591,13 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
||||
[self listenTombstoneEventNotifications];
|
||||
[self listenMXSessionStateChangeNotifications];
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Observe kAppDelegateDidTapStatusBarNotification.
|
||||
kAppDelegateDidTapStatusBarNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kAppDelegateDidTapStatusBarNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self setBubbleTableViewContentOffset:CGPointMake(-self.bubblesTableView.adjustedContentInset.left, -self.bubblesTableView.adjustedContentInset.top) animated:YES];
|
||||
}];
|
||||
|
||||
@@ -661,9 +669,13 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
||||
[AppDelegate theDelegate].visibleRoomId = self.roomDataSource.roomId;
|
||||
}
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Observe network reachability
|
||||
kAppDelegateNetworkStatusDidChangeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kAppDelegateNetworkStatusDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[self refreshActivitiesViewDisplay];
|
||||
|
||||
}];
|
||||
@@ -673,6 +685,8 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
||||
// Observe missed notifications
|
||||
mxRoomSummaryDidChangeObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXRoomSummaryDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
MXRoomSummary *roomSummary = notif.object;
|
||||
|
||||
if ([roomSummary.roomId isEqualToString:self.roomDataSource.roomId])
|
||||
@@ -1398,8 +1412,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
||||
}
|
||||
if (URLPreviewDidUpdateNotificationObserver)
|
||||
{
|
||||
[NSNotificationCenter.defaultCenter removeObserver:URLPreviewDidUpdateNotificationObserver];
|
||||
URLPreviewDidUpdateNotificationObserver = nil;
|
||||
[NSNotificationCenter.defaultCenter removeObserver:URLPreviewDidUpdateNotificationObserver];
|
||||
}
|
||||
|
||||
[self removeCallNotificationsListeners];
|
||||
@@ -1555,8 +1568,12 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
||||
|
||||
- (void)registerURLPreviewNotifications
|
||||
{
|
||||
MXWeakify(self);
|
||||
|
||||
URLPreviewDidUpdateNotificationObserver = [NSNotificationCenter.defaultCenter addObserverForName:URLPreviewDidUpdateNotification object:nil queue:NSOperationQueue.mainQueue usingBlock:^(NSNotification * _Nonnull notification) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
// Ensure this is the correct room
|
||||
if (![(NSString*)notification.userInfo[@"roomId"] isEqualToString:self.roomDataSource.roomId])
|
||||
{
|
||||
@@ -4768,10 +4785,14 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
||||
|
||||
- (void)listenCallNotifications
|
||||
{
|
||||
MXWeakify(self);
|
||||
|
||||
kMXCallStateDidChangeObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXCallStateDidChange object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
MXCall *call = notif.object;
|
||||
if ([call.room.roomId isEqualToString:customizedRoomDataSource.roomId])
|
||||
if ([call.room.roomId isEqualToString:self->customizedRoomDataSource.roomId])
|
||||
{
|
||||
[self refreshActivitiesViewDisplay];
|
||||
[self refreshRoomInputToolbar];
|
||||
@@ -4779,16 +4800,20 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
||||
}];
|
||||
kMXCallManagerConferenceStartedObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXCallManagerConferenceStarted object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
NSString *roomId = notif.object;
|
||||
if ([roomId isEqualToString:customizedRoomDataSource.roomId])
|
||||
if ([roomId isEqualToString:self->customizedRoomDataSource.roomId])
|
||||
{
|
||||
[self refreshActivitiesViewDisplay];
|
||||
}
|
||||
}];
|
||||
kMXCallManagerConferenceFinishedObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXCallManagerConferenceFinished object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
NSString *roomId = notif.object;
|
||||
if ([roomId isEqualToString:customizedRoomDataSource.roomId])
|
||||
if ([roomId isEqualToString:self->customizedRoomDataSource.roomId])
|
||||
{
|
||||
[self refreshActivitiesViewDisplay];
|
||||
[self refreshRoomInputToolbar];
|
||||
@@ -5839,8 +5864,12 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
|
||||
|
||||
- (void)listenMXSessionStateChangeNotifications
|
||||
{
|
||||
MXWeakify(self);
|
||||
|
||||
kMXSessionStateDidChangeObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionStateDidChangeNotification object:self.roomDataSource.mxSession queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
if (self.roomDataSource.mxSession.state == MXSessionStateSyncError
|
||||
|| self.roomDataSource.mxSession.state == MXSessionStateRunning)
|
||||
{
|
||||
|
||||
@@ -77,8 +77,7 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
|
||||
}
|
||||
|
||||
func start(with spaceId: String?) {
|
||||
self.currentSpaceId = spaceId
|
||||
|
||||
|
||||
// If start has been done once do not setup view controllers again
|
||||
if self.hasStartedOnce == false {
|
||||
let masterTabBarController = self.createMasterTabBarController()
|
||||
@@ -105,9 +104,13 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
|
||||
versionCheckCoordinator.start()
|
||||
add(childCoordinator: versionCheckCoordinator)
|
||||
}
|
||||
|
||||
self.updateMasterTabBarController(with: spaceId, forceReload: true)
|
||||
} else {
|
||||
self.updateMasterTabBarController(with: spaceId)
|
||||
}
|
||||
|
||||
self.updateMasterTabBarController(with: spaceId)
|
||||
|
||||
self.currentSpaceId = spaceId
|
||||
}
|
||||
|
||||
func toPresentable() -> UIViewController {
|
||||
@@ -280,7 +283,9 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
|
||||
gesture.delegate = self
|
||||
}
|
||||
|
||||
private func updateMasterTabBarController(with spaceId: String?) {
|
||||
private func updateMasterTabBarController(with spaceId: String?, forceReload: Bool = false) {
|
||||
|
||||
guard forceReload || spaceId != self.currentSpaceId else { return }
|
||||
|
||||
self.updateTabControllers(for: self.masterTabBarController, showCommunities: spaceId == nil)
|
||||
self.masterTabBarController.filterRooms(withParentId: spaceId, inMatrixSession: self.currentMatrixSession)
|
||||
|
||||
@@ -299,13 +299,12 @@ final class NavigationRouter: NSObject, NavigationRouterType {
|
||||
self.postNotification(withName: NavigationRouter.willPopModule, for: viewController)
|
||||
}
|
||||
|
||||
private func didPopViewController(_ viewController: UIViewController) {
|
||||
private func didPopViewController(_ viewController: UIViewController) {
|
||||
self.postNotification(withName: NavigationRouter.didPopModule, for: viewController)
|
||||
|
||||
// Call completion closure associated to the view controller
|
||||
// So associated coordinator can be deallocated
|
||||
runCompletion(for: viewController)
|
||||
|
||||
self.postNotification(withName: NavigationRouter.didPopModule, for: viewController)
|
||||
|
||||
self.removeModule(for: viewController)
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
RoomVC: Fix retain cycles that prevents `RoomViewController` to be deallocated.
|
||||
Reference in New Issue
Block a user