Talk about the iOS singleton pattern

  • 2020-06-01 11:04:40
  • OfStack

The singleton pattern is a common software design pattern. It contains only one special class called a singleton in its core structure. The singleton mode can ensure that there is only one instance of a class in the system and the instance is easy to be accessed, so as to control the number of instances and save system resources. If you want only one object of a class to exist in the system, the singleton pattern is the best solution.

1. Writing steps

1) create a class method and return an object instance, starting with shared default current.
2) create a global variable to hold the reference of the object
3) determine whether the object exists. If it does not, create the object

2. Several patterns of specific singleton patterns

The first singleton pattern


// Non-thread-safe writing 

static UserHelper * helper = nil;

+ (UserHelper *)sharedUserHelper {

if (helper == nil) {

helper = [[UserHelper alloc] init];

}

 return helper;

}

The second singleton pattern


// Thread-safe writing 1

static UserHelper * helper = nil;

+ (UserHelper *)sharedUserHelper {

 @synchronized(self) {

  

  if (helper == nil) {

   helper = [[UserHelper alloc] init];

  }

 }

 return helper;

}

The third singleton pattern


+ (void)initialize {

 

 if ([self class] == [UserHelper class]) {

  helper = [[UserHelper alloc] init];

 }

}

The fourth singleton pattern


// Thread-safe writing 3 (apple recommends, mostly this) 

static UserHelper * helper = nil;

+ (UserHelper *)sharedUserHelper {

 

static dispatch_once_t onceToken;

 dispatch_once(&onceToken, ^{

  helper = [[UserHelper alloc] init];

 });

 

 return helper;

}

MRC fully implements singletons (understand)


#import <Foundation/Foundation.h>

#import "UserHelper.h"

 

void func() {

 

 static dispatch_once_t onceToken;

 dispatch_once(&onceToken, ^{

 NSLog(@"haha");

 });

}

 

int main(int argc, const char * argv[]) {

 @autoreleasepool {

 

// [UserHelper logout];

 

 if ([UserHelper isLogin]) {

  

  UserHelper * helper = [UserHelper sharedUserHelper];

  NSLog(@"username = %@ password = %@",helper.userName,helper.password);

  

 } else {

  

  char name[20];

  char pwd[20];

  NSLog(@" Please enter a user name ");

  scanf("%s",name);

  NSLog(@" Please enter your password ");

  scanf("%s",pwd);

  

  NSString * userName = [[NSString alloc] initWithUTF8String:name];

  NSString * password = [[NSString alloc] initWithUTF8String:pwd];

  

  if (userName && password) {

  

  [UserHelper loginWithUserName:userName password:password];

  

  UserHelper * helper = [UserHelper sharedUserHelper];

  NSLog(@"username = %@ password = %@",helper.userName,helper.password);

  

  }

 }

 

// UserHelper * help1 = [UserHelper sharedUserHelper];

// help1.userName = @"dahuan";

// help1.password = @"123456";

// NSLog(@"%p",help1);

// NSLog(@"%@",help1.userName);

// NSLog(@"%@",help1.password);

//

// 

// UserHelper * help2 = [UserHelper sharedUserHelper];

// help2.password = @"zxc";

// NSLog(@"%p",help2);

// NSLog(@"%@",help1.userName);

// NSLog(@"%@",help1.password);

 

 }

 return 0;

}

 //class.h

#import <Foundation/Foundation.h>

 

@interface UserHelper : NSObject

 

//1 Create a class method and return an object instance  shared default current

 

+ (UserHelper *)sharedUserHelper;

 

@property (nonatomic, copy) NSString * userName;

 

@property (nonatomic, copy) NSString * password;

 

+ (BOOL)isLogin;

 

+ (void)loginWithUserName:(NSString *)userName password:(NSString *)password;

 

+ (void)logout;

 

@end

 

// class.m

#import "UserHelper.h"

 

//2 , create, 1 Global variables 

 

#define Path @"/Users/dahuan/Desktop/data"

 

static UserHelper * helper = nil;

 

@implementation UserHelper

 

//+ (void)initialize {

// 

// if ([self class] == [UserHelper class]) {

// helper = [[UserHelper alloc] init];

// }

//}

 

+ (UserHelper *)sharedUserHelper {

 

 //3 , determine whether the object exists, if not, create the object 

 // Thread safety 

// @synchronized(self) {

// 

// if (helper == nil) {

//  helper = [[UserHelper alloc] init];

// }

// }

 

 //gcd  Thread safety 

 static dispatch_once_t onceToken;

 dispatch_once(&onceToken, ^{

 helper = [[UserHelper alloc] init];

 });

 

 return helper;

}

 

- (instancetype)init {

 

 if (self = [super init]) {

 

 NSString * data = [NSString stringWithContentsOfFile:Path encoding:NSUTF8StringEncoding error:nil];

 if (data) {

  NSArray * array = [data componentsSeparatedByString:@"-"];

  _userName = array[0];

  _password = array[1];

 }

 }

 return self;

}

 

+ (BOOL)isLogin {

 

 UserHelper * helper = [UserHelper sharedUserHelper];

 if (helper.userName && helper.password) {

 return YES;

 }

 return NO;

}

 

+ (void)loginWithUserName:(NSString *)userName password:(NSString *)password {

 

 UserHelper * helper = [UserHelper sharedUserHelper];

 helper.userName = userName;

 helper.password = password;

 

 NSArray * array = @[userName,password];

 NSString * data = [array componentsJoinedByString:@"-"];

 [data writeToFile:Path atomically:YES encoding:NSUTF8StringEncoding error:nil];

}

 

+ (void)logout {

 

 NSFileManager * fm = [NSFileManager defaultManager];

 

 if ([fm fileExistsAtPath:Path]) {

 [fm removeItemAtPath:Path error:nil];

 }

}

 

@end

That's all about the iOS singleton. I hope it will help you.


Related articles: