[iOS] fix crash when deleting last incognito tab.

In some circumstances, |connectedScenes| can contain a scene with
no associated SceneController while cleaning up after the last OTR tab.

This CL ensures that when this happens, the nil controller isn't added
to the controller array.

(Root cause for this state is unclear; some comments are added here as
well to guide future investigations).

Bug: 1142782
Change-Id: I33617e6e2252a2124870430c2eefc2cb4158a28c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2506440
Commit-Queue: Mark Cogan <[email protected]>
Reviewed-by: Robbie Gibson <[email protected]>
Cr-Commit-Position: refs/heads/master@{#822260}
diff --git a/ios/chrome/app/application_delegate/app_state.mm b/ios/chrome/app/application_delegate/app_state.mm
index 6429849..2adfdc7 100644
--- a/ios/chrome/app/application_delegate/app_state.mm
+++ b/ios/chrome/app/application_delegate/app_state.mm
@@ -200,7 +200,6 @@
 
 - (void)setMainSceneState:(SceneState*)mainSceneState {
   DCHECK(!_mainSceneState);
-
   _mainSceneState = mainSceneState;
   [self.observers appState:self sceneConnected:mainSceneState];
 }
@@ -577,7 +576,8 @@
       for (UIWindowScene* scene in connectedScenes) {
         if (![scene.delegate isKindOfClass:[SceneDelegate class]]) {
           // This might happen in tests.
-          // TODO(crbug.com/1113097): This shouldn't be needed.
+          // TODO(crbug.com/1113097): This shouldn't be needed. (It might also
+          // be the cause of crbug.com/1142782).
           [sceneStates addObject:[[SceneState alloc] initWithAppState:self]];
           continue;
         }
diff --git a/ios/chrome/browser/ui/main/scene_controller.mm b/ios/chrome/browser/ui/main/scene_controller.mm
index 4cb0cda..033d5ec1 100644
--- a/ios/chrome/browser/ui/main/scene_controller.mm
+++ b/ios/chrome/browser/ui/main/scene_controller.mm
@@ -2390,9 +2390,14 @@
 
   NSMutableArray<SceneController*>* sceneControllers =
       [[NSMutableArray alloc] init];
-  for (SceneState* sceneState in self.sceneState.appState.connectedScenes) {
+  for (SceneState* sceneState in [self.sceneState.appState connectedScenes]) {
     SceneController* sceneController = sceneState.controller;
-    [sceneControllers addObject:sceneController];
+    // In some circumstances, the scene state may still exist while the
+    // corresponding scene controller has been deallocated.
+    // (see crbug.com/1142782).
+    if (sceneController) {
+      [sceneControllers addObject:sceneController];
+    }
   }
 
   for (SceneController* sceneController in sceneControllers) {