Edit to highlight the previously third option and the way I now manage this problem:
I would use Source Control to tag each version - so that it is easy to get back to the code for a previous version. It should be possible to check-out the tagged project in a separate folder (I use Subversion for this).
Once you have the older version in a separate directory then change the Bundle Identifier - add on the tag name and build etc. When changing the bundle identifier - make sure that you do not change the initial number and the app should still work with your provisioning profile. This assumes that you have a wildcard provisioning profile that you are using for development. If you need to include Nofifications or the In-App purchases this may not be possible.
=============================
Previous version of answer:
I have a quick trick that I use to hold versions - I use different versions of the Simulator and during development I keep moving between the different versions. If you are doing this with the simulator you can also move the files around.
However on the device then you are going to have to change your bundle identifier as mentioned. I would edit the bundle version each time I would like to freeze the functions and move on to a new phase.
Another option would be to use your version control to tag each of your versions allowing you to go back to the previous versions as seperate projects should you need to and you could then alter the bundle identifier and install as a seperate version.
Now I have written this reply I think I will starting using option 3 and tagging my versions better in SVN and use this method as it is a little less random than having to remember what version is in which simulator and it will allow me to deploy on devices too.