iOS - Note Singleton created

The first written singleton created: Multithreaded dispatch_once

General writing:

#import <Foundation/Foundation.h>


@interface FNWaterMarkHelper : NSObject


+ (instancetype)sharedWaterMark;  

@end
#import "FNUserInfoManager.h"
static FNWaterMarkHelper *_showWaterMark = nil;

+ (instancetype)sharedWaterMark{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _showWaterMark = [[self alloc] init];
    });
    
    return _showWaterMark;
}


@end

Output test:

#import <Foundation/Foundation.h>  
#import "Downloader.h"  
  
int main(int argc, const char * argv[]) {  
    @autoreleasepool {  
        FNWaterMarkHelper *obj1 = [FNWaterMarkHelper sharedWaterMark];  
        NSLog(@"obj1 = %@", obj1);  
          
        FNWaterMarkHelper *obj2 = [FNWaterMarkHelper sharedWaterMark];  
        NSLog(@"obj2 = %@", obj2);  
          
        FNWaterMarkHelper *obj3 = [[FNWaterMarkHelper alloc] init];  
        NSLog(@"obj3 = %@", obj3);  
    }  
      
    return 0;  
}  

result:

obj1 = <Downloader: 0x78f25be0>  
obj2 = <Downloader: 0x78f25be0>  
obj3 = <Downloader: 0x79225e00>  

Explanation:

We can see, when we get to call the sharedWaterMark method of the object is the same, but when we construct the object by alloc and init, the resulting object is not the same.

The question then comes, we get different objects in different ways, it is clearly not acceptable. We must ensure the uniqueness of the object, so we need to block users by alloc and init and copy objects to construct this road.

Creating objects into application memory (alloc), initialization (init) these two steps, we want to ensure the uniqueness of the object, so the first step in this stage we have to intercept it. When we call alloc method, internal OC will call this method to apply allocWithZone memory, we override this method, then call sharedWaterMark method returns a singleton object in this method, so that we can achieve our goal. Copy of the object is the same principle, copyWithZone override method and the method call returns sharedDownloader singletons in this method.

Improve:

#import "FNUserInfoManager.h"
static FNWaterMarkHelper *_showWaterMark = nil;

+ (instancetype)sharedWaterMark{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _showWaterMark = [[super allocWithZone:NULL] init];
    });
    
    return _showWaterMark;
}

+ (id)allocWithZone:(struct _NSZone *)zone {  
    return [FNWaterMarkHelper sharedWaterMark];  
}  
  
- (id)copyWithZone:(struct _NSZone *)zone {  
    return [FNWaterMarkHelper sharedWaterMark];  
}  

@end

Output:

obj1 = <Downloader: 0x7ca42e70>  
obj2 = <Downloader: 0x7ca42e70>  
obj3 = <Downloader: 0x7ca42e70>  

Get!

 

Singleton constructor to create the second method, not commonly used:

static PublicUtils *DefaultManager = nil;

+(instancetype)sharedUtils
{
    if (!DefaultManager)
        DefaultManager = [[self allocWithZone:NULL] init];
    
    return DefaultManager;
}

 

Guess you like

Origin www.cnblogs.com/qiyiyifan/p/10965729.html