單例模式

一 單例模式--基本實現

做用:能夠保證在程序運行過程,一個類只有一個實例,並且該實例易於外界訪問atom

1,懶漢式(經常使用):第一次用到單例對象時,再建立

#import "MusicTool.h"
@interface HMMusicTool ()
@property (strong, nonatomic) NSMutableArray *music; //.h
@end
@implementation MusicTool

-(NSArray *)music
{
    if (_music == nil) {
        _music = [NSMutableArray array];
    }
    return _music;
}
static id _musicTool;
+ (id)allocWithZone:(struct _NSZone *)zone
{       
        if (_musicTool == nil){ //避免屢次加鎖
        @synchronized(self) { //加鎖,避免屢次加載
            if (_musicTool == nil) { // 防止建立屢次
                _musicTool = [super allocWithZone:zone];
            }
        }
     }
    return _musicTool;
}
+(instancetype)shareMusiclTool
{    
    if (_musicTool == nil){ //避免屢次加鎖
    @synchronized(self){
        if (_musicTool == nil) {
            _musicTool = [[self alloc] init];
        }
    }
 }  
    return _musicTool;
}

- (id)copyWithZone:(NSZone *)zone
{
    return _musicTool;
}

#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    MusicTool *tool = [[MusicTool alloc] init];
    MusicTool *tool1 = [[MusicTool alloc] init];
    MusicTool *tool2 = [MusicTool shareMusiclTool];
    MusicTool *tool3 = [tool1 copy];
    NSLog(@"%p %p %p %p",tool.music,tool1.music,tool2.music,tool3.music);
    //返回的結果都是相同的指針,全部只有一個實例
 }

2,餓漢式:一進入程序就建立一個單例對象

/**
 *  當類加載到OC運行環境中(內存),就會調用一次
 */
+ (void)load
{
    _moiveTool = [[self alloc] init];
}
/**
 *  當第一次使用這個類的時候纔會調用
 */
+ (void)initialize
{
    NSLog(@"-------initialize");
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
    /**
     *  load當即調用alloc,因此不須要加鎖
     */
    if (_moiveTool == nil) {//防止頻繁alloc
        return [super allocWithZone:zone];
    }
    return _moiveTool;
}

+ (instancetype)shareMoiveTool
{
    return _moiveTool;
}

- (id)copyWithZone:(NSZone *)zone
{
    return _moiveTool;
}

3,CGD-ARC模式

#import "SingTool.h"
@implementation SingTool
//用來保存惟一的單例對象
static id _instance;

+(instancetype)allocWithZone:(struct _NSZone *)zone
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}

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

//copy多是已存在_instance,因此直接返回
-(id)copyWithZone:(NSZone *)zone
{
    return _instance;
}

4,CGD-非ARC模式

#import "SingTool.h"

@implementation SingTool
//用來保存惟一的單例對象
static id _instance;

+(instancetype)allocWithZone:(struct _NSZone *)zone
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}

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

//copy多是已存在_instance,因此直接返回
-(id)copyWithZone:(NSZone *)zone
{
    return _instance;
}

//重寫release,retain,retainCount,autorelease方法
//重寫release,執行release時候不進行操做
-(oneway void)release
{
    
}

- (instancetype)retain
{
    return self;
}
-(NSUInteger)retainCount
{
    return 1;
}
-(instancetype)autorelease
{
    return self;
}


一 單例模式--完善

1,使用宏定義文件

1,直接用宏定義文件,無需額外本身寫
//GCD
//.h文件
#define SingletionH(name)  +(instancetype)share##name;

//.m文件
#if __has_feature(objc_arc)

#define SingletionM(name)  \
static id _instance; \
\
+(instancetype)allocWithZone:(struct _NSZone *)zone \
{                                                   \
    static dispatch_once_t onceToken;               \
    dispatch_once(&onceToken, ^{                    \
        _instance = [super allocWithZone:zone];     \
    });                                             \
    return _instance;                               \
}                                                   \
                                                    \
+(instancetype)share##name                          \
{                                                   \
    static dispatch_once_t onceToken;               \
    dispatch_once(&onceToken, ^{                    \
        _instance = [[self alloc] init];            \
    });                                             \
    return _instance;                               \
}                                                   \
                                                    \
-(id)copyWithZone:(NSZone *)zone                    \
{                                                   \
    return _instance;                               \
}                                                   

#else

#define SingletionM(name)  \
static id _instance; \
\
+(instancetype)allocWithZone:(struct _NSZone *)zone \
{                                                   \
    static dispatch_once_t onceToken;               \
    dispatch_once(&onceToken, ^{                    \
        _instance = [super allocWithZone:zone];     \
    });                                             \
    return _instance;                               \
}                                                   \
                                                    \
+(instancetype)share##name                          \
{                                                   \
    static dispatch_once_t onceToken;               \
    dispatch_once(&onceToken, ^{                    \
        _instance = [[self alloc] init];            \
});                                                 \
    return _instance;                               \
}                                                   \
                                                    \
-(id)copyWithZone:(NSZone *)zone                    \
{                                                   \
    return _instance;                               \
}                                                   \
-(oneway void)release                           \
{                                               \
                                                \
}                                               \
- (instancetype)retain                          \
{                                               \
    return self;                                \
}                                               \
-(NSUInteger)retainCount                        \
{                                               \
    return 1;                                   \
}                                               \
-(instancetype)autorelease                      \
{                                               \
    return self;                                \
}

#endif

2,環境條件編譯

    
#if __has_feature(objc_arc)
    //編譯器是ARC環境
    NSLog(@"ARC環境");
#else
    //編譯器是MRC環境
    NSLog(@"MRC環境");
#endif

}
相關文章
相關標籤/搜索