Day7 oc singleton pattern

OC singleton pattern

The singleton pattern is a pattern that is often used in ios, such as [UIApplicationsharedApplication] (to get the current application object), [UIDevicecurrentDevice] (to get the current device object), and there are many ways to write the singleton pattern.

 

There are three conditions for implementing the singleton pattern (from http://blog.csdn.net/jiangwei0910410003/article/details/41928053)

For these three conditions in OC

1. The constructor of the class is private

We only need to rewrite the allocWithZone method so that the initialization operation is performed only once

2. The class provides a class method to generate an object

This can directly define a class method

3. The class has a private own object

We can define a property in the .m file

The first: non-thread-safe, and the simplest implementation

In Singleton.h, a class method is provided in the .h file for generating objects

 

#import <Foundation/Foundation.h>

//The purpose of designing a simple interest class is to limit this class to only create one object
//Constructor is private
//Save a global static variable
@interface Singleton : NSObject
+ (Singleton *)shareInstance;
@end

 Singleton.m

 

 

#import "Singleton.h"
//Define an object of static type
static Singleton * singleton = nil;//Cannot be accessed externally, and placed in a static block

@implementation singleton
//Provide a class method to get a single instance
+ (Singleton *)shareInstance{
    if(!singleton){
        // Calling the alloc method here will enter the following allocWithZone method
        singleton = [[self alloc] init];
    }
    return singleton;
}
// Rewriting allocWithZone here mainly prevents [[AdressBook alloc] init] from returning multiple objects if called multiple times in this way  
+ (id) allocWithZone:(NSZone *)zone{
    if(!singleton){
        singleton = [super allocWithZone:zone];
        return singleton;
    }
    return nil;
}
//Other methods also need to be rewritten
//copy method
- (id)copyWithZone:(NSZone *)zone{
    return singleton;;
}

//Need to rewrite the retain method, can't let it reference +1
- (id)retain{
    return self;
}

//The release method needs to be rewritten, and it cannot be referenced by -1
- (oneway void)release{
    //do Nothing...
}
- (unsigned)retainCount  {  
    return UINT_MAX;  //denotes an object that cannot be released 
- (id)autorelease{
    return self;
}

@end

 

 

main.m

 

#import <Foundation/Foundation.h>

#import "Singleton.h"
//Simple interest mode
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        Singleton * singleton1 = [Singleton shareInstance];
        Singleton * singleton2 = [Singleton shareInstance];
        
        NSLog(@"%@", singleton1);//The two pointers point to the same object
        NSLog(@"%@", singleton2);
        
    }
    return 0;
}

 

 

The second: Apple has provided a more official way of writing objective c singletons (adding thread safety to prevent multiple instances from being created under multi-threading)

 

static Singleton *sharedSingletonManager = nil;
 
+ (Singleton*)sharedManager
{
    //Add thread safety to prevent multiple threads from creating multiple instances
    @synchronized(self) {
        if (sharedSingletonManager == nil) {
            [[self alloc] init]; // assignment not done here
        }
    }
    return sharedSingletonManager;
}
 
+ (id)allocWithZone:(NSZone *)zone
{
    @synchronized(self) {
        if (sharedSingletonManager == nil) {
            sharedSingletonManager = [super allocWithZone:zone];
            return sharedSingletonManager;  // assignment and return on first allocation
        }
    }
    return nil; //on subsequent allocation attempts return nil
}
 
- (id)copyWithZone:(NSZone *)zone
{
    return self;
}
 
- (id)retain
{
    return self;
}
 
- (unsigned)retainCount
{
    return UINT_MAX;  //denotes an object that cannot be released
}
 
- (void)release
{
    //do nothing
}
 
- (id)autorelease
{
    return self;
}

 

 The third type: ARC technology is generally used after iOS5. It turns out that this way of writing is cumbersome, and release is no longer used. Can be combined with GCD to implement the singleton pattern

ARC

ARC is a new feature introduced in iOS 5, the full name is ARC (Automatic Reference Counting).

Simply put, retain/release is automatically added to the code, and the code that needs to be manually added to deal with reference counting for memory management can be automatically completed by the compiler. When used, it is through the specified syntax that the compiler (LLVM 3.0) automatically generates the reference count management part of the instance code when compiling the code. ARC is not GC, it's just a static analyzer tool.

GCD
GCD is the marketing name for libdispatch, which is an Apple library that provides strong support for concurrent code execution on multicore hardware (running iOS or OS X). It has the following advantages:
1. GCD can improve the responsiveness of your application by deferring expensive computational tasks and running them in the background.
2. GCD provides an easy-to-use concurrency model rather than just locks and threads to help us avoid concurrency traps.
3. GCD has the potential to optimize your code with more performant primitives on common patterns such as singletons.
+ (Singleton*) sharedManager
{
  static Singleton *sharedSingletonManager = nil;
  static dispatch_once_t pred;
  dispatch_once(&pred, ^{
    sharedSingletonManager = [[self alloc] init]; // or some other init method
  });
  return sharedSingletonManager;
}
 From the above code, we can see that the implementation of singleton under ARC is similar to that under non-ARC, except that there is no overloaded memory management function. And this also benefits from the ARC technology.

Fourth singleton factory

        (taken from http://blog.jobbole.com/56439/)

In actual programming work, as the scale of the project continues to expand, we often find that there are a large number of singletons in the entire project. So we will encounter a problem how to manage these singletons. At the same time, it is also necessary to prevent a lot of duplicate code. So to manage these singletons, we naturally think of the factory pattern.

For detailed implementation, see https://github.com/yishuiliunian/DZSinglonFactory.git

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326987906&siteId=291194637