Copy gives you a separate object.
In general, you should just be using retain, unless you explicitly want to make copies of objects. Each time you copy you have to release, so keep that in mind.
A good time to use -copy is when you're going to be using enumeration to add or remove objects.
Take an array, for instance. If you are enumerating the array, you can't add or remove objects to it during the enumeration, or you will crash. Before starting enumeration, use -copy to create a new copy of the array, and as you're enumerating, if you need to add/remove an object (mutate), you can do so on the copy.
When you're finished with the enumeration you can set the copy back to the original.