Let’s see the traditional C ways for clearing up of unused objects is a bit of a nightmare. There are no ways in the language like how should be approached.
Imagine one function A create one object and pass it to another function B now both are using the same data now the problem is who is: the responsible for deleting it if it no longer used? and let’s say we have one function who is also gonna use the same data than what?
The solution is there are conventions and design patterns to handle these situations, that’s the reason the reference counting was developed and management technique used in Obj-C.
What we have in Obj-C
Obj-C uses reference counting as its Memory Management Technique so according to that each object keeps an internal count of how many times it’s needed. So only in case of, if count drops to zero. Yes you can compare it with Garbage Collector we have in Java but it’s not like automatic some chunk of code getting executed and removing the objects which ones are not needed.
Most important thing is Object Ownership it means an object owner is someone that has explicitly said: “I need that object, don’t delete”. So one object can have more than one owner.
If object owner is not using it they have the responsibility to tell so that the reference count should be decreased by one. So while dealing with Obj-C pointers/Objects it’s really good to send correct messages.
alloc, it will allocate a fresh instance of the object, set the reference count +1.
new, shortest way to write alloc&init.
retain, you passed the object and you want to tell you to need that so its reference count should be increased by 1 again.
autorelease, need object temporarily and want to delete once you did with the operations.
copy creates a new copy of the object.
dealloc, opposite of init method, automatically get called right before the object is destroyed.
Static methods used for allocating the initializing objects directly but are aware that you are not the owner of that object, once the scope of your program finish it will be removed. Ex: [NSString stringWithFormat:@”Say %@”,@”Hello”];
It’s an instance of NSAutoreleasePool, objects which are to be auto released. You can also send a message to autorelease or create object using convenience methods. So once the object added into autorelease pool and when the pool is popped, all the objects will be deleted.
Retain cycle is a condition where two objects strongly maintain a reference to each other and stop each other from being released. For example, let we have two classes as.
@interface Parent : NSObject
@property (nonatomic, strong) Child *child;
@interface Child : NSObject
@property (nonatomic, strong) Parent * parent;
So, at some point of time when creating object of any of these class as
Parent *parent = [[Parent alloc] init];
Child *child = [[Child alloc] init];
parent.child = child;
child.parent = parent;
Here the parent object maintaining a strong reference of Child class and child object maintaining a strong reference of Parent class in back. So, both parent and child object having a reference count of one and one. Both objects will get released from memory only when their reference count will reach to zero but in this scenario, this will not be going to happen ever because both are mutually pointing to each other a dead lock is get created here. This situation is called the Retain Cycle that will lead to memory leaks.
Fortunately, it’s very easy to fix this problem—just tell one of the properties to maintain a weak reference to the other object so, what’s this weak and strong reference means??
Strong Reference: A strong reference says that don’t release this object till I m owning this.
Weak Reference: A weak reference says that don’t release this object until someone else pointing this strongly.
Just like strong and __strong, weak and __weak keywords are there for declaring properties and instance variables respectively as a weakly referenced object.
Quick Tips and common mistakes
Think about strong and weak pointers as well as retain cycles, Avoid unnecessary caching, Don’t declare every object globally unnecessarily, use Xcode Instruments such as static analyzer and find the potential memory leaks and fix them
Arrays, Dictionaries and other objects that contain any object generally retain objects once you add it to them. It means once you create an object the reference count will be 1 and once you add it into an Arrays it will be 2.
Releasing the Object that you don’t own, let’s say if creating a new object using convenience method than there is no need to release that.
Keeping and using an Object that you don’t Own.
Calling dealloc directly. So never call dealloc by the way you have to call init after calling alloc its kinda default constructor for init the default value of the object.
Over-releasing. Accidentally you’re releasing something twice instead of once. You can also track these crashes by just enabling Zombies.
Retain Cycles. When an object released there is a cascading effect, the root object released its children’s as well and so on. Let’s say there is some condition like A owns B and B owns An as they own each other.