Click here to Skip to main content
15,882,017 members
Articles / Mobile Apps / iOS

Handling NSInvalidArgumentException “Pushing the same view controller instance more than once is not supported” in an iOS Application

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
5 Apr 2023CPOL2 min read 5.1K   1  
How to handle NSInvalidArgumentException in an iOS app
This blog post discusses options to handle the NSInvalidArgumentException in an iOS app.

When debugging my iOS app, I discovered that the following apparently innocent code sometimes caused the app to crash due to an NSInvalidArgumentException, “Pushing the same view controller instance more than once is not supported”:

C
[devNavController pushViewController:myVC animated:YES];

The crash happens when there are too many opened applications and as the error message suggests, it happens because the user clicks on the same button again causing the code to push the same view controller twice into the navigation controller, which is prohibited in iOS.

My first attempt is to handle the crash with try/catch:

C
@try {
   [devNavController pushViewController:myVC animated:YES];
} @catch (NSException * e) {
    NSLog(@"Exception: %@", e);
}

Although you may say that try/catch should never be used in Objective C as all possible error conditions should have been checked prior to executing codes that might generate exceptions, this is not possible in many cases. After all, how can a programmer predict all possible error scenarios that might happen? And if programmers are indeed not supposed to use try/catch in Objective-C, why does the language still have such a construct? In my case, I have successfully used try/catch many times in Objective-C in non-critical background codes where all that is needed is to hide the error from the users. For example, in one of my applications, an exception in a background task that updates the contact autocomplete database (as retrieved from the phone’s address book) can probably be ignored as the same task can be executed again without any major impact on application functionality since the user can still live without autocomplete for a while and simply type the number manually.

I proceeded to run the modified code with try/catch, and guess what, the exception still crashed the app, as if the try/catch construct was never added. The only thing that worked in the end is to check if the same view controller is already to the navigation stack, and do not push it again if this is the case:

C
if(![self.navigationController.topViewController isKindOfClass:[MyViewController class]]) {
   [devNavController pushViewController:myVC animated:YES];
}

But why didn’t try/catch work in the first place? Perhaps the above NSInvalidArgumentException behaves likes java.lang.Error in the Java language. That is, it can only be handled by catching whatever is the equivalent on java.lang.Error in Objective-C, and not by catching NSException like what I tried in the above code. Or perhaps this is simply an iOS bug. Whatever the reason, this is just another quirk in the Objective-C language that developers simply have to live with.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Writer
Singapore Singapore
Since 2008, ToughDev has been publishing technical sharing articles on a wide range of topics from software development to electronics design. Our interests include, but are not limited to, Android/iOS programming, VoIP products, embedded design using Arduino/PIC microcontrollers, reverse-engineering, retro-computing, and many others. We also perform product reviews, both on new and vintage products, and share our findings with the community. In addition, our team also develops customized software/hardware solutions highly adapted to suit your needs. Contact us for more information.

Comments and Discussions

 
-- There are no messages in this forum --