What have you tried?
What have you done to actually debug this? Did you use the debugger? Set breakpoints at strategic locations in your view controllers, so you can see where it goes? Did you add NSLog statements? What sequence of execution did they show?
Now, usually other users would expect me to post some code. However, I firmly believe no code is necessary here, so instead of posting code, I will just tell you all what's supposed to happen, and what is actually happing.
What's supposed to happen: When I press a button in a view controller, the app first checks the database to see if the name of a Nib file is in there. Absent said name, the app takes me to a predefined view controller. When I am done with that view controller, the app takes me to another view controller and updates its database so that, until I am done with that view controller, the app will load the view controller from the controller's nib file.
What actually happens: The app saves the name of the second view controller's NIB file.
Your descriptions are difficult to follow because you don't clearly identify the view controllers by giving them names. Even names like Alice, Bob, Carol, and Dave would be better than what you have. Then in your "What actually happens", you say "second view controller" without stating its name, and without using the same adjectival phrase (i.e. you don't call it "second view controller" in your first description).
You also fail to identify in the "actually happens" part the entirety of what has actually happened. You give the end result, but you don't say how it got there. Thus, we're left to conclude that some, all, or maybe only parts of the "What should happen" may or may not have been executed. We don't know, because you didn't post any log of what was actually executed, what points were reached, and who or what might actually have produced "the name of the second view controller's NIB file", i.e. the actual output.
In short, you've described the final output, but nothing about how it got there or was produced.
Finally, one of the reasons for posting code is because computers don't execute descriptions written in everyday language. They only execute descriptions written in code. Your code precisely describes to the computer what it will do; it does not describe your intent. Nor does a description of your intent tell the computer what to do; it only tells humans (including yourself) what the actual code should do.
Your non-code description of what should happen is at best a rewrite or paraphrase of what you
think your code says. The actual code could say something else. Rewrites and paraphrases invariably lose something in the translation. If you wrote it before writing code, then it's a first draft. The actual code could say something slightly different, or say it in a way that its execution isn't identical to your description of intent.
We have no way of knowing what the computer is actually doing except by seeing the code. You could have made any number of unseen errors that cause the code to not reflect your intention. If the intent was written first, the code is a translation of that. If your posted description was written after the code, then that description is a translation of the code. Neither one is a precise substitute for the other.
This is also why we ask for you to describe your intention, because if the intent doesn't match the code, we might see it. But unless we know the intent (the expected execution and result), all we know is the actual code. We only have a possibility of discovering what's wrong by knowing two things (code and intent), not just one (code or intent).
Debugging is a process of comparing actual results with expected results. If one of those is missing, no debugging is possible. A result is produced, but is it the right one? No one can tell unless they know what the expected result is. The same logic applies at every step of execution: compare actuality to expectation. Take one away, you can't tell anything.
Comparison of two things is fundamental to all problem solving.