Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Side by Side Diff: ios/chrome/browser/tabs/tab_model.mm

Issue 2809543003: [ios] Change WebStateListObserverBridge to use weak reference. (Closed)
Patch Set: Fix DCHECK in WebStateList's ObserverList destructor. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | ios/chrome/browser/web_state_list/web_state_list_fast_enumeration_helper.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "ios/chrome/browser/tabs/tab_model.h" 5 #import "ios/chrome/browser/tabs/tab_model.h"
6 6
7 #include <cstdint> 7 #include <cstdint>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 std::unique_ptr<WebStateList> _webStateList; 138 std::unique_ptr<WebStateList> _webStateList;
139 139
140 // Helper providing NSFastEnumeration implementation over the WebStateList. 140 // Helper providing NSFastEnumeration implementation over the WebStateList.
141 base::scoped_nsobject<WebStateListFastEnumerationHelper> 141 base::scoped_nsobject<WebStateListFastEnumerationHelper>
142 _fastEnumerationHelper; 142 _fastEnumerationHelper;
143 143
144 // WebStateListObservers reacting to modifications of the model (may send 144 // WebStateListObservers reacting to modifications of the model (may send
145 // notification, translate and forward events, update metrics, ...). 145 // notification, translate and forward events, update metrics, ...).
146 std::vector<std::unique_ptr<WebStateListObserver>> _webStateListObservers; 146 std::vector<std::unique_ptr<WebStateListObserver>> _webStateListObservers;
147 147
148 // Strong references to id<WebStateListObserving> wrapped by non-owning
149 // WebStateListObserverBridges.
150 base::scoped_nsobject<NSArray<id<WebStateListObserving>>>
151 _retainedWebStateListObservers;
152
148 // The delegate for sync. 153 // The delegate for sync.
149 std::unique_ptr<TabModelSyncedWindowDelegate> _syncedWindowDelegate; 154 std::unique_ptr<TabModelSyncedWindowDelegate> _syncedWindowDelegate;
150 155
151 // Counters for metrics. 156 // Counters for metrics.
152 WebStateListMetricsObserver* _webStateListMetricsObserver; 157 WebStateListMetricsObserver* _webStateListMetricsObserver;
153 158
154 // Backs up property with the same name. 159 // Backs up property with the same name.
155 std::unique_ptr<TabUsageRecorder> _tabUsageRecorder; 160 std::unique_ptr<TabUsageRecorder> _tabUsageRecorder;
156 // Backs up property with the same name. 161 // Backs up property with the same name.
157 const SessionID _sessionID; 162 const SessionID _sessionID;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 DCHECK([_observers empty]); 199 DCHECK([_observers empty]);
195 200
196 // browserStateDestroyed should always have been called before destruction. 201 // browserStateDestroyed should always have been called before destruction.
197 DCHECK(!_browserState); 202 DCHECK(!_browserState);
198 203
199 [[NSNotificationCenter defaultCenter] removeObserver:self]; 204 [[NSNotificationCenter defaultCenter] removeObserver:self];
200 205
201 // Clear weak pointer to WebStateListMetricsObserver before destroying it. 206 // Clear weak pointer to WebStateListMetricsObserver before destroying it.
202 _webStateListMetricsObserver = nullptr; 207 _webStateListMetricsObserver = nullptr;
203 208
204 [self closeAllTabs]; 209 // Close all tabs. Do this in an @autoreleasepool as WebStateList observers
210 // will be notified (they are unregistered later). As some of them may be
211 // implemented in Objective-C and unregister themselves in their -dealloc
212 // method, ensure they -autorelease introduced by ARC are processed before
213 // the WebStateList destructor is called.
214 @autoreleasepool {
215 [self closeAllTabs];
216 }
205 217
206 // Unregister all observers after closing all the tabs as some of them are 218 // Unregister all observers after closing all the tabs as some of them are
207 // required to properly clean up the Tabs. 219 // required to properly clean up the Tabs.
208 for (const auto& webStateListObserver : _webStateListObservers) 220 for (const auto& webStateListObserver : _webStateListObservers)
209 _webStateList->RemoveObserver(webStateListObserver.get()); 221 _webStateList->RemoveObserver(webStateListObserver.get());
210 _webStateListObservers.clear(); 222 _webStateListObservers.clear();
223 _retainedWebStateListObservers.reset();
211 224
212 _clearPoliciesTaskTracker.TryCancelAll(); 225 _clearPoliciesTaskTracker.TryCancelAll();
213 226
214 [super dealloc]; 227 [super dealloc];
215 } 228 }
216 229
217 #pragma mark - Public methods 230 #pragma mark - Public methods
218 231
219 - (Tab*)currentTab { 232 - (Tab*)currentTab {
220 web::WebState* webState = _webStateList->GetActiveWebState(); 233 web::WebState* webState = _webStateList->GetActiveWebState();
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 // Set up the usage recorder before tabs are created. 289 // Set up the usage recorder before tabs are created.
277 _tabUsageRecorder = base::MakeUnique<TabUsageRecorder>(self); 290 _tabUsageRecorder = base::MakeUnique<TabUsageRecorder>(self);
278 } 291 }
279 _syncedWindowDelegate = 292 _syncedWindowDelegate =
280 base::MakeUnique<TabModelSyncedWindowDelegate>(self); 293 base::MakeUnique<TabModelSyncedWindowDelegate>(self);
281 294
282 // There must be a valid session service defined to consume session windows. 295 // There must be a valid session service defined to consume session windows.
283 DCHECK(service); 296 DCHECK(service);
284 _sessionService.reset([service retain]); 297 _sessionService.reset([service retain]);
285 298
286 _webStateListObservers.push_back(base::MakeUnique< 299 base::scoped_nsobject<NSMutableArray<id<WebStateListObserving>>>
287 WebStateListObserverBridge>([ 300 retainedWebStateListObservers([[NSMutableArray alloc] init]);
288 [TabModelClosingWebStateObserver alloc] 301
289 initWithTabModel:self 302 base::scoped_nsobject<TabModelClosingWebStateObserver>
290 restoreService:IOSChromeTabRestoreServiceFactory::GetForBrowserState( 303 tabModelClosingWebStateObserver([[TabModelClosingWebStateObserver alloc]
291 _browserState)])); 304 initWithTabModel:self
305 restoreService:IOSChromeTabRestoreServiceFactory::
306 GetForBrowserState(_browserState)]);
307 [retainedWebStateListObservers addObject:tabModelClosingWebStateObserver];
308
309 _webStateListObservers.push_back(
310 base::MakeUnique<WebStateListObserverBridge>(
311 tabModelClosingWebStateObserver));
312
292 _webStateListObservers.push_back( 313 _webStateListObservers.push_back(
293 base::MakeUnique<SnapshotCacheWebStateListObserver>( 314 base::MakeUnique<SnapshotCacheWebStateListObserver>(
294 [SnapshotCache sharedInstance])); 315 [SnapshotCache sharedInstance]));
295 if (_tabUsageRecorder) { 316 if (_tabUsageRecorder) {
296 _webStateListObservers.push_back( 317 _webStateListObservers.push_back(
297 base::MakeUnique<TabUsageRecorderWebStateListObserver>( 318 base::MakeUnique<TabUsageRecorderWebStateListObserver>(
298 _tabUsageRecorder.get())); 319 _tabUsageRecorder.get()));
299 } 320 }
300 _webStateListObservers.push_back(base::MakeUnique<TabParentingObserver>()); 321 _webStateListObservers.push_back(base::MakeUnique<TabParentingObserver>());
322
323 base::scoped_nsobject<TabModelSelectedTabObserver>
324 tabModelSelectedTabObserver(
325 [[TabModelSelectedTabObserver alloc] initWithTabModel:self]);
326 [retainedWebStateListObservers addObject:tabModelSelectedTabObserver];
301 _webStateListObservers.push_back( 327 _webStateListObservers.push_back(
302 base::MakeUnique<WebStateListObserverBridge>( 328 base::MakeUnique<WebStateListObserverBridge>(
303 [[TabModelSelectedTabObserver alloc] initWithTabModel:self])); 329 tabModelSelectedTabObserver));
330
331 base::scoped_nsobject<TabModelObserversBridge> tabModelObserversBridge(
332 [[TabModelObserversBridge alloc] initWithTabModel:self
333 tabModelObservers:_observers.get()]);
334 [retainedWebStateListObservers addObject:tabModelObserversBridge];
304 _webStateListObservers.push_back( 335 _webStateListObservers.push_back(
305 base::MakeUnique<WebStateListObserverBridge>( 336 base::MakeUnique<WebStateListObserverBridge>(tabModelObserversBridge));
306 [[TabModelObserversBridge alloc]
307 initWithTabModel:self
308 tabModelObservers:_observers.get()]));
309 337
310 auto webStateListMetricsObserver = 338 auto webStateListMetricsObserver =
311 base::MakeUnique<WebStateListMetricsObserver>(); 339 base::MakeUnique<WebStateListMetricsObserver>();
312 _webStateListMetricsObserver = webStateListMetricsObserver.get(); 340 _webStateListMetricsObserver = webStateListMetricsObserver.get();
313 _webStateListObservers.push_back(std::move(webStateListMetricsObserver)); 341 _webStateListObservers.push_back(std::move(webStateListMetricsObserver));
314 342
315 for (const auto& webStateListObserver : _webStateListObservers) 343 for (const auto& webStateListObserver : _webStateListObservers)
316 _webStateList->AddObserver(webStateListObserver.get()); 344 _webStateList->AddObserver(webStateListObserver.get());
345 _retainedWebStateListObservers.reset([retainedWebStateListObservers copy]);
317 346
318 if (window) { 347 if (window) {
319 DCHECK([_observers empty]); 348 DCHECK([_observers empty]);
320 // Restore the session and reset the session metrics (as the event have 349 // Restore the session and reset the session metrics (as the event have
321 // not been generated by the user but by a cold start cycle). 350 // not been generated by the user but by a cold start cycle).
322 [self restoreSessionWindow:window persistState:NO]; 351 [self restoreSessionWindow:window persistState:NO];
323 [self resetSessionMetrics]; 352 [self resetSessionMetrics];
324 } 353 }
325 354
326 // Register for resign active notification. 355 // Register for resign active notification.
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 } 819 }
791 820
792 // Called when UIApplicationWillEnterForegroundNotification is received. 821 // Called when UIApplicationWillEnterForegroundNotification is received.
793 - (void)applicationWillEnterForeground:(NSNotification*)notify { 822 - (void)applicationWillEnterForeground:(NSNotification*)notify {
794 if (_tabUsageRecorder) { 823 if (_tabUsageRecorder) {
795 _tabUsageRecorder->AppWillEnterForeground(); 824 _tabUsageRecorder->AppWillEnterForeground();
796 } 825 }
797 } 826 }
798 827
799 @end 828 @end
OLDNEW
« no previous file with comments | « no previous file | ios/chrome/browser/web_state_list/web_state_list_fast_enumeration_helper.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698