web-dev-qa-db-de.com

"Die gleiche View-Controller-Instanz mehr als einmal zu verschieben, wird nicht unterstützt"

Ich verwende den folgenden Code, um einige Nachrichten abzurufen und in meinen Posteingang zu legen. 

MyInboxVC *inboxVC=[MyInboxVC get ];
//upload all the pending messages
UINavigationController *devNavController=[[MyappMgr get]getDeveloperNavigationController ];

[devNavController pushViewController:inboxVC animated:YES];
[devNavController setNavigationBarHidden:NO];

Ich bekomme die Ausnahme 

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Pushing the same view controller instance more than once is not supported (<MyInboxVC: 0x1452a0>)'

Was heißt das? Was mache ich falsch?

40
Suchi

Ich glaube, wenn Sie einige Aktionen wirklich schnell ausführen, kann dies auch passieren. Ich baue so etwas ein:

if(![self.navigationController.topViewController isKindOfClass:[YOURCLASS class]]) {

bearbeiten//

dies geschieht häufiger auf alten Geräten mit langsamen Animationen wie dem iPhone 3 oder 3gs

68
Melvin

Behandeln Sie zuerst den Absturz, damit Ihre App nicht zerstört wird:

@try {
    [self.navController pushViewController:viewController animated:NO];
} @catch (NSException * e) {
    NSLog(@"Exception: %@", e);
} @finally {
    //NSLog(@"finally");
}

Wenn Sie den Fehler erhalten, verwenden Sie popTo

- (void)pushViewController:(UIViewController *)viewController {
  if (viewController) {
    @try {
        [self.navController pushViewController:viewController animated:NO];
    } @catch (NSException * ex) {
        //“Pushing the same view controller instance more than once is not supported” 
        //NSInvalidArgumentException
        NSLog(@"Exception: [%@]:%@",[ex  class], ex );
        NSLog(@"ex.name:'%@'", ex.name);
        NSLog(@"ex.reason:'%@'", ex.reason);
        //Full error includes class pointer address so only care if it starts with this error
        NSRange range = [ex.reason rangeOfString:@"Pushing the same view controller instance more than once is not supported"];

        if ([ex.name isEqualToString:@"NSInvalidArgumentException"] &&
           range.location != NSNotFound) {
            //view controller already exists in the stack - just pop back to it
            [self.navController popToViewController:viewController animated:NO];
        } else {
            NSLog(@"ERROR:UNHANDLED EXCEPTION TYPE:%@", ex);
        }
    } @finally {
        //NSLog(@"finally");
    }
  } else {
    NSLog(@"ERROR:pushViewController: viewController is nil");
  }
}
19
brian.clear

Dies bedeutet, dass sich die von [MyInboxVC get] zurückgegebene ViewController bereits im Navigationsstapel von devNavController befindet. Sie können dasselbe Objekt nicht mehrmals zum Stapel hinzufügen. 

Anscheinend haben Sie bereits eine MyInboxVC zuvor gedrückt. Stellen Sie sicher, dass Sie es geknackt haben, als es nicht mehr benötigt wurde. 

Das ist die "Was ist gemeint" Antwort, aber Sie haben nicht genug Informationen, um zu wissen, was Sie tun müssen, um das Problem zu beheben.

Meine Vermutung ist, dass Ihr Navigations-Stack größer wird, als Sie erwarten, was bedeutet, dass Sie nicht so oft knallen, wie Sie sollten.

6
MarkPowell

Führen Sie dies als Teil eines Segments durch? In diesem Fall müssen Sie keinen VC auf den Navigationscontroller schieben, da dies bereits durch das Segue erledigt wird. Deshalb tritt Ihr Fehler auf - Sie drücken ein VC, das sich bereits auf dem Stack des NavControllers befindet.

5
micnguyen

Dies bedeutet, dass Sie dasselbe Viewcontroller-Objekt erneut zum Stapeln bringen, wenn es bereits dort ist.

[self.navigationController pushViewController:viewControllerObj animated:NO];

[self.navigationController pushViewController:viewControllerObj animated:NO];

prüfen Sie, ob Sie innerhalb einer Schleife gedrückt haben oder ob Sie den Code aus Versehen mehr als einmal platziert haben.

3
Durai Amuthan.H

Dies passierte für mich, als ein Klick auf die Schaltfläche mit dem Balken zu schnell geschah, und es war schwer zu reproduzieren, es sei denn, Sie waren verrückt nach den Tastenanschlägen. Das Folgende wurde behoben, indem die Schaltfläche deaktiviert wurde, der Nav-Push gestartet und dann die Schaltfläche im Haupt-Thread aktiviert wurde (da sie nach der Animation vom Push aus aufgerufen wurde).

- (void)showMore
{
    self.navigationItem.leftBarButtonItem.enabled = NO;
    [self.navigationController pushViewController:moreVC animated:YES];
    [self.navigationItem.leftBarButtonItem performSelectorOnMainThread:@selector(setEnabled:) withObject:@(YES) waitUntilDone:NO];
}
1
pulse4life

Der Hauptgrund für dieses Problem ist offensichtlich, wenn der Code, der den View-Controller gedrückt hat, mehr als einmal aufgerufen wird. Dies kann aus vielen Gründen auftreten. Dies ist der häufigste Fehler, wenn eine Callback-Methode von einem Hintergrundthread ausgelöst wird, wobei diese Methode mehr als einmal ausgeführt werden könnte, während der View-Controller noch gedrückt wird. Beispiel: Das Aufrufen eines Service-APIs im Hintergrundthread, wenn Sie auf eine Schaltfläche tippen. Dadurch können Sie die Taste mehrmals drücken. Daher wird der Rückruf, der den View-Controller drückt, mehrmals aufgerufen. @ Die Lösung von Melvin und @Sam ist gültig, solange Sie das ursprüngliche Problem nicht beheben möchten, indem Sie nicht mehr als einmal drücken. 

1
Elie

Dies ist ein erwartetes Verhalten von UINavigationController, bei dem eine Ausnahme ausgelöst wird, wenn versucht wird, einen bereits im Stapel vorhandenen Ansichtscontroller zu pushen (Es ist dort ab iOS 2.2). 

1
Sivaprasad

Stellen Sie sicher, dass Sie den View-Controller nicht zweimal im Navigations-Stack hinzufügen Beispiel - in dem Beispiel self.mainViewC wird zweimal gedrückt, da es zunächst im navController instanziiert wird und anschließend in der letzten Zeile erneut auf den navController verschoben wird , was dieses Problem verursachen würde.

  navController=[[UINavigationController alloc] initWithRootViewController:self.mainViewC];  
  self.window.rootViewController = navController;
  [self.window makeKeyAndVisible];        
  [navController pushViewController:self.mainViewC animated:NO]; 

In diesem Fall wurde mainViewC bereits zum Stack hinzugefügt, als initWithRootViewController geschrieben wurde. Es ist kein PushViewController mehr erforderlich. 

0
Kavish

Ich habe das gleiche Problem (Swift 4) mit IB segue behoben mit: 

override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
    return navigationController?.topViewController is MainController ? true : false 
}
0
fethica

Eine andere Option, die ich erfahren habe, ist, dass [MyInboxVC get] überhaupt keine Instanz eines MyInboxVC-Objekts zurückgibt. Ein deutliches Zeichen dafür wäre, dass der Fehler besagt, dass "dasselbe View-Controller-Exemplar mehrmals gedrückt wird (nichtTheInboxVC: 0x9e31660)", dh. die Klasse, die mehr als einmal geschoben wird, wird nicht von MyInboxVC erwartet (ein Durchfall von MyInboxVC wird nicht zugewiesen)

0
arcady bob