Correct, when an application launches the OS allocates memory for the application and that memory is split into three segments: the stack (where local variables, return values, all things related to calling a function are stored), the data segment (also known as the code segment, this is where instructions are stored) and heap.
I’m glossing over a few things here, but the general gist of these segments are as follows:
Memory in the code segment is invariable. You don’t have to worry about it.
Memory in the stack is handled automatically, that is, when you call a method, a chunk of the stack (called a frame) is allocated. Any local variables or return values are stored here and when the method exits, the frame is destroyed. You don’t have to worry about it.
The heap is where you dynamically allocate memory as needed. All Objective-C instances are allocated from the heap. You must manage this memory manually.
When the application terminates, the entire chunk of memory allocated to your application (stack, heap, data) is returned to the OS for use by another application. Therefore, the only reason you manage memory is because you want to be able to allocate objects while your application is running. If you just kept using memory from the heap, your application eventually would not be able to allocate any more objects. And then it would crash.