It is simple if you just follow the published rules. Seriously. It's only hard because you're trying to work out the implementation.
You never have to understand refcounts or worry about the overall state of allocated memory. All you have to do is write each class, function, or method to manage its owned objects. It only gets confusing when you try to figure out how the overall system is implemented, and how retain/release actually work.
When you call fopen() on a file pathname, do you worry about how the OS reads directory entries, figures out the block on the disk, and then caches it in memory? Do you concern yourself with the differences between FAT, HFS, or NTFS? Not if you want to stay sane. It's the same thing with retain/release. Commit the rules of object ownership to memory (yours, not the computer's), and everything will work as if by magic, without you having to understand the least little bit of how it's implemented.
Understand the principles, use the abstractions, and follow the rules. You can dig into the implementation details later, if and when it becomes necessary.