Singleton Class in Objective-C
Last Updated :
01 Dec, 2023
Objective-C serves as a programming language widely employed to construct applications intended for both macOS and iOS. Among the many design patterns that find extensive usage in Objective-C, the Singleton pattern proves quite noteworthy. A Singleton represents a class in that instantiation remains restricted to a single instance throughout the entire application. In this discourse, we delve into the Singleton pattern and its implementation in Objective-C.
What is a Singleton Class?
The Singleton paradigm denotes a class instantiation restricted to a singular occurrence across the entire application. It establishes a global access point allowing all objects to connect with it. Such a pattern is preferred for shared resources, enabling a sole entry point, thus minimizing resource creation redundancies.
Benefits of Singleton Class
- Provides a single point of access to shared resources.
- Ensures that these resources are not created unnecessarily.
- Can improve performance by reducing memory allocation.
Implementing Singleton Class in Objective-C
There are two approaches to implementing a Singleton class in Objective-C:
Approach 1: Using a Static Instance Variable
This method involves using a static instance variable to retain the sole instance of the class, with the variable initialized to nil when the class is first loaded. Upon the calling of the shared instance method, an assessment is conducted to determine if the instance variable is nil. Should it be found empty, a new class instance is generated, and assigned to the variable. On the other hand, if it is non-nil, the current class instance is returned.
Below is the Objective-C program to implement a singleton class using static instance variables.
ObjectiveC
#import <Foundation/Foundation.h>
@interface MyClass : NSObject < NSCopying >
+ (MyClass *)sharedInstance;
@end
@implementation MyClass
static MyClass *sharedInstance = nil ;
+ (MyClass *)sharedInstance
{
if (sharedInstance == nil )
{
sharedInstance = [[ super allocWithZone: NULL ] init];
}
return sharedInstance;
}
+ ( id )allocWithZone:( NSZone *)zone
{
return [ self sharedInstance];
}
- ( id )copyWithZone:( NSZone *)zone
{
return self ;
}
- ( id )init
{
self = [ super init];
if ( self != nil )
{
}
return self ;
}
@end
int main( int argc, const char * argv[])
{
MyClass *myObject1 = [MyClass sharedInstance];
MyClass *myObject2 = [MyClass sharedInstance];
if (myObject1 == myObject2)
{
NSLog ( @"Both objects are the same instance" );
}
else
{
NSLog ( @"Objects are different instances" );
}
return 0;
}
|
Output:
Â
Explanation:
- The present algorithm generates a singleton class entitled “MyClass” through the initial method, which is done by establishing a static variable that can hold the shared instance.Â
- This class contains the “sharedInstance” method, which determines whether the shared instance has already been generated and, if not, constructs a new instance using the “allocWithZone” technique from its superclass.Â
- It also supersedes the “allocWithZone” and “copyWithZone” methods to make sure that the same shared instance is always given out.
- In the main function, two instances of the “MyClass” class are generated through the “sharedInstance” technique, and their memory locations are evaluated to verify whether they refer to the same instance or not (which they ought to, given that “sharedInstance” method returns the same instance each time it is accessed).Â
- The program then shows a message stating whether or not the two instances are identical and returns 0 to indicate that the program has concluded successfully.
Approach 2: Using dispatch_once
To guarantee the thread safety of the Singleton class initialization process, the dispatch_once function is utilized in this method. The function is invoked once throughout the entire lifetime of the application, ensuring synchronization and safety. Upon the calling of the sharedinstance method, the dispatch_once function comes into play, generating the sole instance of the class.
Below is the Objective-C program to implement a singleton class using a dispatch_once:
ObjectiveC
#import <Foundation/Foundation.h>
@interface MyClass : NSObject
+ (MyClass *)sharedInstance;
@end
@implementation MyClass
static MyClass *sharedInstance = nil ;
+ (MyClass *)sharedInstance
{
if (sharedInstance == nil )
{
sharedInstance = [[ super allocWithZone: NULL ] init];
}
return sharedInstance;
}
+ ( id )allocWithZone:( NSZone *)zone
{
return [ self sharedInstance];
}
- ( id )copyWithZone:( NSZone *)zone
{
return self ;
}
- ( id )init
{
return sharedInstance;
}
@end
int main( int argc, const char * argv[])
{
MyClass *instance1 = [MyClass sharedInstance];
MyClass *instance2 = [MyClass sharedInstance];
if (instance1 == instance2)
{
NSLog ( @"Both objects are the same instance" );
}
else
{
NSLog ( @"Objects are different instances" );
}
return 0;
}
|
Output:
Explanation:
- This code creates a “singleton” class called MyClass, which means only one instance of the class can exist at a time.Â
- The code achieves this by creating a static variable that holds the shared instance of the class and overriding certain methods to ensure that the shared instance is always returned.
- In the main function, two instances of MyClass are created using the sharedInstance method, and the code checks if they are the same object.Â
- Since sharedInstance always returns the same instance of the class, both instance1 and instance2 point to the same object, and the code prints a message confirming this.
Conclusion
Both approaches have their advantages and disadvantages. The first approach is simpler to implement, but it is not thread-safe. The second approach is thread-safe, but it is more complex to implement. It is important to choose the right approach based on the specific requirements of the application.
Share your thoughts in the comments
Please Login to comment...