iOS开发实践之多线程(单例模式)

时间:2023-03-08 15:42:49

  单例模式的作用:可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问,从而方便地控制了实例个数,并节约系统资源。

  单例模式的使用场合:在这个应用程序中,共享一份资源(这份资源只需要创建初始化1次)。
一、单例模式-ARC

  1、在.m中保留一个全局的static的实例(static防止其他类extern引用 修改值)

  static id_instance;

  2、重写allocWithZone:方法,在这里创建唯一的实例(注意线程安全)

  + (id)allocWithZone:(struct _NSZone *)zone {

   if (_instance == nil) { // 防止频繁加锁

   @synchronized(self) {

              if (_instance == nil) { // 防止创建多次

   _instance = [super allocWithZone:zone];

     }

   }

  }

    return _instance;

  }

  3、提供1个类方法让外界访问唯一的实例

+ (instancetype)sharedMusicTool {

if (_instance == nil) { // 防止频繁加锁

@synchronized(self) {

if (_instance == nil) { // 防止创建多次

_instance = [[self alloc] init];

}

}

}

return _instance;

}

4、实现copyWithZone:方法

- (id)copyWithZone:(struct _NSZone *)zone {

return _instance;

}

5、如果要实现饿汉式的单例,就实现load方法。(建议不使用)

//当类加载到OC运行时环境中(内存),就会调用一次(一个类只会加载1次)

+(void)load{
    _instance = [[self alloc] init];
}

音乐单例工具类型字代码:

MusicTool.h

#import<UIKit/UIKit.h>

@interface MusicTool:UIView

//提供1个类方法让外界访问唯一的实例

+(instancetype)shareMusicTool;

@end

MusicTool.m

//单例模式:懒汉式

@implementation MusicTool

static id _instance;//static防止其他类extern引用 修改值

/**

* 如果要实现饿汉式的单例,就实现load方法

*  当类加载到OC运行时环境中(内存),就会调用一次(一个类只会加载1次)

*/

//+(void)load{

//    _instance = [[self alloc] init];

//}

   //当第一次使用这个类的时候才会调用

    //+(void)initialize{

//    NSLog(@"===initialize===");

//}

/** alloc 方法内部调用这个方法*/

 + (id)allocWithZone:(struct _NSZone *)zone {

   if (_instance == nil) { // 防止频繁加锁

   @synchronized(self) {

              if (_instance == nil) { // 防止创建多次

   _instance = [super allocWithZone:zone];

     }

   }

  }

    return _instance;

  }

/**

实例化类

*/

+ (instancetype)sharedMusicTool {

if (_instance == nil) { // 防止频繁加锁

@synchronized(self) {

if (_instance == nil) { // 防止创建多次

_instance = [[self alloc] init];

}

}

}

return _instance;

}

/**

实例化类

*/

+ (instancetype)sharedMusicTool {

if (_instance == nil) { // 防止频繁加锁

@synchronized(self) {

if (_instance == nil) { // 防止创建多次

_instance = [[self alloc] init];

}

}

}

return _instance;

}

  二:单例模式 – 非ARC

非ARC中(MRC),单例模式的实现(比ARC多了几个步骤)

实现内存管理方法

- (id)retain { return self; }

- (NSUInteger)retainCount { return 1; }

- (oneway void)release {}

- (id)autorelease { return self; }

MusicTool.m

@implementation MusicTool

static id _instance;  //static 防止其它类extern引用 修改值

+(id)allocWithZone:(struct _NSZone *)zone{}

+(instancetype)sharedMusicTool{}

-(id)copyWithZone:(NSZone *)zone{}同上

//重写release方法,不释放

  -(oneway void)release{

  }

   //重写retain方法,返回单例类

  -(instancetype)retain{

      return self; //return _instance;

   }

  //计算永远为1

  -(NSUInteger)retainCount{

      return 1;

   }

测试:

MusicTool *mt1 = [[MusicTool alloc] init];

MusicTool *mt2 = [MusicTool sharedMusicTool];

MusicTool *mt3 = [mt2 copy];

[mt2 release];//非arc环境下release

地址完全一样!

三:单例模式在ARC\MRC环境下的写法有所不同,可以用宏判断是否为ARC环境

#if __has_feature(objc_arc)

// ARC

#else

// MRC

#endif

把单例定义成宏,抽出公共类

1、HMSingleton.h

// .h文件

#define HMSingletonH(name) + (instancetype)shared##name;

// .m文件

#if __has_feature(objc_arc)

#define HMSingletonM(name) \

static id _instace; \

\

+ (id)allocWithZone:(struct _NSZone *)zone \

{ \

static dispatch_once_t onceToken; \

dispatch_once(&onceToken, ^{ \

_instace = [super allocWithZone:zone]; \

}); \

return _instace; \

} \

\

+ (instancetype)shared##name \

{ \

static dispatch_once_t onceToken; \

dispatch_once(&onceToken, ^{ \

_instace = [[self alloc] init]; \

}); \

return _instace; \

} \

\

- (id)copyWithZone:(NSZone *)zone \

{ \

return _instace; \

}

#else

#define HMSingletonM(name) \

static id _instace; \

\

+ (id)allocWithZone:(struct _NSZone *)zone \

{ \

static dispatch_once_t onceToken; \

dispatch_once(&onceToken, ^{ \

_instace = [super allocWithZone:zone]; \

}); \

return _instace; \

} \

\

+ (instancetype)shared##name \

{ \

static dispatch_once_t onceToken; \

dispatch_once(&onceToken, ^{ \

_instace = [[self alloc] init]; \

}); \

return _instace; \

} \

\

- (id)copyWithZone:(NSZone *)zone \

{ \

return _instace; \

} \

\

- (oneway void)release { } \

- (id)retain { return self; } \

- (NSUInteger)retainCount { return 1;} \

- (id)autorelease { return self;}

#endif

2、要想再整个项目中都能使用这个宏,则要在预编译pch文件中import导入这个头文件

#ifdef __OBJC__

#import <UIKit/UIKit.h>

#import <Foundation/Foundation.h>

#import "HMSingleton.h"

#endif

3、使用HMSingleton工具类,实现HMMusicTool单例

HMMusicTool.h

#import <Foundation/Foundation.h>

@interface HMMusicTool : NSObject

//宏定义的方法

HMSingletonH(MusicTool)

@end

HMMusicTool.m

#import "HMMusicTool.h"

@implementation HMMusicTool

//宏定义的方法

HMSingletonM(MusicTool)

@end

4.测试:

HMMusicTool *tool1 = [HMMusicTool sharedMusicTool];

HMMusicTool *tool2 = [HMMusicTool sharedMusicTool];

HMMusicTool *tool3 =[[HMMusicTool alloc]init];

HMMusicTool *tool4 =[tool3 copy];

地址相同!