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

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

  单例模式的使用场合:在这个应用程序中,共享一份资源(这份资源只需要创建初始化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 allocinit];

            }

        }

    }

    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 allocinit];

            }

        }

    }

    return _instance;

}

/**

实例化类

*/

+ (instancetype)sharedMusicTool {

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

        @synchronized(self) {

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

               _instance = [[self allocinit];

            }

        }

    }

    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];  

地址相同!

posted @ 2017-06-12 14:45  姜晓延  阅读(294)  评论(0编辑  收藏  举报