Design patterns are often considered a more advanced topic and therefore ignored or overlooked by people new to iOS or OS X development. However, there are a number of design patterns every aspiring iOS or OS X developer will be faced with from day one. The singleton pattern is one such pattern.
In a strict implementation, a singleton is the sole allowable instance of a class in the current process. But you can also have a more flexible singleton implementation in which a factory method always returns the same instance, but you can allocate and initialize additional instances.
A singleton object acts as a kind of control center, directing or coordinating the services of the class. Your class should generate a singleton instance rather than multiple instances when there is conceptually only one instance.
To create a singleton as the sole allowable instance of a class in the current process, you need to have an implementation similar to below. This code does the following:
- It declares a static instance of your singleton object and initializes it to nil.
- In your class factory method for the class (named something like “sharedInstance” or “sharedManager”), it generates an instance of the class but only if the static instance is nil.
- It overrides the allocWithZone: method to ensure that another instance is not allocated if someone tries to allocate and initialize an instance of your class directly instead of using the class factory method. Instead, it just returns the shared object.
- It implements the base protocol methods copyWithZone:, release, retain, retainCount, and autorelease to do the appropriate things to ensure singleton status. (The last four of these methods apply to memory-managed code, not to garbage-collected code.)
Let's put the following code in ServerManager.h, as all we know that the declaration part will be in .h file.
#import <Foundation/Foundation.h>@interface ServerManager : NSObject@property (nonatomic, strong) NSNumber *version;+ (ServerManager*)sharedManager;- (void)getSomeSimpleJSON:(void(^)(id result, NSError *error))completionHandler;@end
And the implementation part will be in ServerManager.m file
#import "ServerManager.h"@implementation ServerManager+ (ServerManager*)sharedManager{static ServerManager *instance = nil;static dispatch_once_t onceToken = 0;dispatch_once(&onceToken, ^{instance = [[super allocWithZone:NULL] init];});return instance;}- (id)init {if ( (self = [super init]) ) {// your custom initialization}return self;}// singleton methods+ (id)allocWithZone:(NSZone *)zone {return [self sharedManager];}- (id)copyWithZone:(NSZone *)zone {return self;}- (void)getSomeSimpleJSON:(void(^)(id result, NSError *error))completionHandler{NSURL *testURL = [[NSURL alloc]initWithString:@"https://api.github.com/users/mralexgray/repos"];
[[[NSURLSession sharedSession]dataTaskWithURL:testURLcompletionHandler:^(NSData * _Nullable data,NSURLResponse * _Nullable response,NSError * _Nullable error) {if (!error) {id json = [NSJSONSerialization JSONObjectWithData:dataoptions:NSJSONReadingMutableContainerserror:nil];completionHandler(json,nil);}else{completionHandler(nil,error);}}] resume];}@end
So, let's create demo app to test code in which I'm trying to get some simple JSON response from server. I have SingletonPattern as demo, to create the demo app I used the latest version of xcode-7.1.1. I configured App Transport Security Settings because as we all know about App Transport Security Settings in iOS9. You also don't make sure to configure App Transport Security Settings.
In the demo application we some UI setup.
Finally we are ready to test the singleton class, let's place the below code in ViewController.m
#import "ViewController.h"#import "ServerManager.h"@interface ViewController ()@property (weak, nonatomic) IBOutlet UIView *loaderView;@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *spinner;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view, typically from a nib.
[_spinner startAnimating];__weak ViewController *weakSelf = self;[[ServerManager sharedManager] getSomeSimpleJSON:^(id result, NSError *error) {[weakSelf hideLoading];if (!error) {NSLog(@"%s RESULTS : %@",__PRETTY_FUNCTION__,result);}else{NSLog(@"%s ERROR : %@",__PRETTY_FUNCTION__,error);}}];}
- (void)hideLoading{[_spinner stopAnimating];[_loaderView setHidden:YES];}- (void)didReceiveMemoryWarning {[super didReceiveMemoryWarning];// Dispose of any resources that can be recreated.}@end
Download example code here
Conclusion
If your are clear with explanation, now your are very enthusiastic to implement the singleton object pattern in your next project. If you have any doubt comment below. Want to know more
0 Comments