Open In App

Memory Management in Objective-C

Last Updated : 06 Dec, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Memory management is a core concept irrespective of any programming language. The process of allocation of memory of objects when needed and deallocation when they are no longer in use is called Memory Management. Memory is a limited resource and so has to be dealt with carefully. If unrequired memory is not freed gradually you run out of memory leading to the suffering performance of your computer and in worst-case scenarios it can even crash your computer. Efficient Memory management concerns us with time, cost, and resource-saving which can be achieved in Objective-C fairly.

In Objective-C memory is managed as follows: 

  1. MRR (Manual Retain Release)
  2. ARC (Automatic Reference Counting)

Manual Retain Release(MRR)

MRR(Manual Retain Release) is also known as Manual Reference Counting(MRC). In Objective-C, all classes are derived from the root class NSObject (here, NS stands for NeXTSTEP) which provides methods for memory management. All NSObject classes are reference counted i.e Objects keep a track of how many times they are referenced by another object. When the reference count turns zero, the object dies and the memory is deallocated.
Retain (Reference count ++) and Release(Reference count –) are special methods that are used to keep track of reference count, where Retain method increases the value of reference count by 1 and the Release method decreases the value of reference count by 1.
According to the MRR technique, we directly manage memory by allocating and deallocating it manually. Therefore, if an object is created it does not die until we do not destroy it. In case, if we create an object and forget to destroy or release the object, it causes Memory Leakage. We may run out of memory if it continues to leak.

MRR BASIC RULES

In MRR, as the name suggests everything is done manually from creating an object, accessing it, retaining an object, releasing it, and destroying the object. Therefore, in order to avoid memory leakage and to the exact track of the reference count there are a few basic rules to remember:

  1. One who creates the object is the owner of the object itself. “alloc”, “new”, “copy” or “mutableCopy” methods are used to create an object and imply you have ownership of the object as well.
  2. One can own an object using retain method. Sometimes methods apart from “alloc”, “new”, “copy” or “mutableCopy” return an object, in that case since you didn’t create the object and so you don’t have ownership of it. But the ownership can be achieved by using the “retain” method as if you have obtained the object with the “alloc” / “new” / “copy” or “mutableCopy” method. Also, if an object is retained x number of times then it has to be released x number of times.
  3.  One must relinquish ownership of an object being owned by using the release or autorelease method when the object is no longer in use. The release method releases the object immediately whereas the autorelease method does not releases the object immediately but sends it into an autorelease pool and releases the object when the pool is drained.
  4. One must not release an object not being owned. Releasing an object we don’t own can crash the application. Crash can occur in cases when we release or access an already destroyed object.
Manual Retain Release(MRR)

 

The life cycle of the object of Class X is represented in the above diagram along with the proper implementation of rules:

An object of class X has been created using the “alloc”/”init” method provided in NSObject class. as an object is created and so the reference count turns 1(Rule 1). 

Some Class Y accesses Class X objects. Since class Y does not own the object “retain” method is used to obtain the object. As retain method is used, it increments the value of the reference count by 1, updating the value of the reference count to 2 (Rule 2).

Class X object has been retained twice by two different classes and therefore, in order to destroy the object and to achieve zero reference count it has to be released twice. Firstly, the reference count currently which is 2 is decreased by 1 when Class X releases the object and becomes 1. At last, when Class Y releases the object, the reference count turns zero, destroying the object(Rule 3).

Further, Class Z made another object that is a copy of the Class X object. Here, a new object is created that has the same instance variables as that of the Class X object here, the reference count turns 1(Rule 1).

Class Z used a release method that decreases the value of the reference count by 1. On decrement, the value of the reference count becomes zero and the object of Class Z is destroyed(Rule 3).

ObjectiveC




#import<Foundation/Foundation.h>
  
@interface my_class:NSObject
-(void)my_method;
@end
  
@implementation my_class
-(void)my_method{
    NSLog(@"It's gonna be allocated 😉 \n");
}
-(void)dealloc{
    NSLog(@"Everything's cleaned up 🙂 \n");
    [super dealloc];
}
@end
  
int main()
{
  
      // some_object_gfg has been created
    my_class *some_object_gfg=[[my_class alloc]init];
    [some_object_gfg my_method];
      
    // Reference count = 1
    NSLog(@"Reference count after allocation :%d",[some_object_gfg retainCount]);
    [some_object_gfg retain];
      
    // Reference count = 1+1 = 2
    NSLog(@"Reference count after retain :%d",[some_object_gfg retainCount]);
    [some_object_gfg release];
      
    // Reference count = 2-1 = 1
    NSLog(@"Reference count after release :%d",[some_object_gfg retainCount]);
    [some_object_gfg release];
      
    some_object_gfg = nil;
      
    // Reference count = 0 
      // Object destroyed
    return 0;    
}


Output:

2022-11-28 08:07:12.546 main[55731] It's gonna be allocated ;) 
2022-11-28 08:07:12.546 main[55731] Reference count after allocation :1
2022-11-28 08:07:12.546 main[55731] Reference count after retain :2
2022-11-28 08:07:12.546 main[55731] Reference count after release :1
2022-11-28 08:07:12.546 main[55731] Everything's cleaned up :) 

Automatic Reference Counting(ARC)

ARC(Automatic Reference Count) was introduced by Apple Inc. in 2011 for application development on its desktop and mobile OS, Mac OS X Lion, and iOS 5. ARC is a more advanced, convenient, and automatic way of memory management. ARC itself inserts proper memory management calls like retain, release, and autorelease for users at compile time based on usage. It also follows the same basic rules discussed above but with little modifications like ownership qualifiers. It reduces long code as the developer needs not to write every retain or release. It also minimizes the risk of memory leakage as the compiler evaluates the life of the object itself. Retain, release, autorelease, or retainCount methods only work with MRR and not ARC. Also, errors show up if we use NSAutoreleasePool instead of @autoreleasepool block. The garbage collection principle is only available for Mac OS X, starting with version 10.5. Also, iOS applications can’t use Garbage collection, since it depends on the power of the device, it will take some time to process, forcing the user to wait to lead to a bad user experience. It is also deprecated since OS X Version 10.8 is in favor of ARC and is scheduled to be removed in the forthcoming versions of OS X. ARC is not a runtime service. It doesn’t follow the garbage collection program execution pattern. Apple says, “ARC in Objective-C makes memory management the job of the compiler”.

ObjectiveC




#import<Foundation/Foundation.h>
  
@interface my_class:NSObject
-(void)my_method;
@end
  
@implementation my_class
-(void)my_method{
    NSLog(@"Using ARC : \n");
}
-(void)dealloc{
    NSLog(@"Everything's cleaned up 🙂 \n");
    [super dealloc];
}
@end
  
int main()
{
    @autoreleasepool{
      
          // Compiler takes care of retain , release or 
          // autorelease itself as it is automatic
        my_class *some_object_gfg = [my_class[alloc]init];
        [some_object_gfg my_method];
        some_object_gfg = nil;
    }
    return 0;
}


Note: This code will not run on an online compiler as it does not support ARC.

Output:

Output

AUTOMATIC REFERENCE COUNTING



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads