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:
SBiOSoftWhare
2021-10-28 20:26:42 +02:00
committed by GitHub
7 changed files with 86 additions and 35 deletions
@@ -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;
+6 -1
View File
@@ -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)
+49 -20
View File
@@ -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)
{
+10 -5
View File
@@ -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)
+2 -3
View File
@@ -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)
}
+1
View File
@@ -0,0 +1 @@
RoomVC: Fix retain cycles that prevents `RoomViewController` to be deallocated.