Memory management in Objective-C

Memory management in Objective-C is critical to iOS and macOS development. It ensures the efficient use of system resources and prevents memory leaks. Objective-C uses a reference-counting model, where objects are retained and released to manage memory allocation.

Memory management methods

In Objective C, methods to manage the memory are as follows:

  • Manual Retain Counting (MRC)

  • Automatic Reference Counting (ARC)

Manual Reference Counting (MRC)

In MRC, developers are responsible for managing the memory by maintaining the count of references to them. All classes are derived from NSObject (NS stands for NeXTSTEP) in Objective-C, which provides methods for memory management. In this model, developers manually retain and release objects to ensure proper memory management.

MRC basic rule

The basic rules of MRC are as follows:

  • Ownership: The one who creates the object is the owner.

  • Retain: When the owner wants to claim ownership of an object, they send it a retain message. This increments the object’s reference count by 1, indicating an additional owner.

  • Release: When developers no longer need an object, they send it a release message. This decrements the object’s reference count by 1. If the reference count drops to 0, meaning there are no more owners, the object is deallocated, and its memory is freed.

  • Autorelease: The autorelease mechanism is used to defer the release of an object until the end of the current autorelease pool’s scope. Objects added to the autorelease pool are sent a release message when drained.

  • Memory leaks: It occurs when an object is not properly released, and its reference count does not reach 0.

  • Retain cycles: A retain cycle occurs when a group of objects references each other so that their reference counts never drop to 0. This leads to memory leaks.

Example

The life cycle of a ClassX object is as follows:

Lifecycle of an object
Lifecycle of an object
  • An object of ClassX has been created, so the reference count is incremented by 1.

  • Another class, let’s call it ClassY, accesses the object of ClassX. However, ClassY does not have ownership of the ClassX object, so it sends a “retain” message, and the reference count is increased by 1 and becomes 2.

  • ClassX decides it no longer needs the object and sends the “release” message to the object, decreasing the reference count from 2 to 1.

  • Now, ClassY is done using the object and sends a “release” message to the object, decreasing the reference count from 1 to 0.

  • As the reference count reaches 0, the object is deallocated, and its memory is freed.

The code of the above example is as follows:

int main(int argc, const char * argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// Step 1: Create an instance of ClassX
ClassX *classXObject = [[ClassX alloc] initWithName:@"ObjectX"];
// Step 2: Create an instance of ClassY and retain the ClassX object
ClassY *classYInstance = [[ClassY alloc] init];
[classYInstance retainClassXObject:classXObject];
// Step 3: Release the ClassX object
[classXObject release];
NSLog(@"ClassX object released. Reference count: %lu.", (unsigned long)[classXObject retainCount]);
// Step 4: Release the ClassY instance
[classYInstance releaseObjects];
// The autorelease pool will automatically release the ClassX object and ClassY instance when drained
[pool drain];
return 0;
}

In the provided code, an object of ClassX is instantiated with an initial reference count of 1. Subsequently, ClassY retains the ClassX object, leading to an increment in the reference count from 1 to 2. Following this, ClassX releases the object, resulting in a decrement of the reference count from 2 to 1. Finally, ClassY releases the object, leading to its proper destruction.

This sequence illustrates the MRC mechanism, highlighting the dynamic adjustments in reference counts as objects are retained and released and appropriately deallocating the resources.

Automatic Reference Counting (ARC)

Automatic reference counting (ARC) is a memory management feature introduced by Apple in Objective-C and Swift programming languages to simplify the process of managing memory. It automates the memory management process by automatically inserting the necessary retain, release, and autorelease messages, reducing errors and making it more efficient.

ARC basic rules

The basic rules of ARC are as follows:

  • Ownership: In ARC, objects are of strong reference by default, but we can use ownership qualifiers, that is, strong, weak, and assign.

  • Retain: It automatically handles retain messages.

  • Release: It automatically handles release messages.

  • Zeroing weak references: ARC supports zeroing weak references, meaning that when the object being referred to is deallocated, the weak reference is automatically set to nil.

  • Autorelease: ARC still uses autorelease pools. For performance optimizations, we can use @autoreleasepool blocks to manage autorelease pool scopes.

  • Retain cycles: Be cautious of retaining cycles even with ARC. Use weak or unowned references to break cycles.

Example

An example of automatic reference counting (ARC) is as below:

int main(int argc, const char * argv[])
{
@autoreleasepool
{
// Step 1: Create an instance of ClassX
ClassX *classXObject = [[ClassX alloc] initWithName:@"ObjectX"];
// Step 2: Create an instance of ClassY and retain the ClassX object
ClassY *classYInstance = [[ClassY alloc] init];
[classYInstance retainClassXObject:classXObject];
// The objects will be automatically released when they go out of scope
return 0;
}
}

This code will not run on the platform as it is using Linux OS, and it does not support ARC.

In this code, an instance of ClassX named classXObject is created using its initWithName: initializer, initializing the objectName property with the value ObjectX. Next, an instance of ClassY named classYInstance is created, and the retainClassXObject: method is called on it, retaining the classXObject within the sharedObject property. The @autoreleasepool block ensures that auto-released objects are deallocated when the block scope is exited. The program returns 0, indicating successful execution.

Conclusion

Memory management in Objective-C has transitioned from Manual Reference Counting (MRC) to Automatic Reference Counting (ARC). ARC automates memory management, reducing manual intervention and potential errors. The choice between MRC and ARC depends on the development environment, emphasizing the importance of a strong understanding of memory management principles in Objective-C.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved