单例模式 - GCD 、兼容ARC和MRC


单例模式 - GCD 、兼容ARCMRC



单例模式的作用:

1,能够保证在程序执行过程。一个类仅仅有一个实例,并且该实例易于供外界訪问

2,从而方便地控制了实例个数,并节约系统资源


单例模式的使用场合:

在整个应用程序中,共享一份资源(这份资源仅仅须要创建初始化1次)


单例模式在ARC\MRC环境下的写法有所不同。须要编写2套不同的代码

能够用宏推断是否为ARC环境

#if __has_feature(objc_arc)

//ARC

#else

//MRC

#endif



在游戏中,音乐在不同的场景可能同样,我们应该仅仅要创建一份,这时候我们就应该使用单例模式。能够节省内存;

ARC环境下,实现单例模式:   代码例如以下:


要使得他们alloc init一份,就能够使用GCDdispatch_once,还能够保证线程安全。

#import "HMAudioTool.h"


@interface HPAudioTool()

@end


@implementation HPAudioTool

//// 定义一份变量(整个程序执行过程中, 仅仅有1)

static id _instance;


- (id)init

{

    if (self = [super init]) {

        static dispatch_once_t onceToken;

        dispatch_once(&onceToken, ^{

            // 载入资源

            

        });

    }

    return self;

}

/**

 *  重写这种方法 : 控制内存内存

 */

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

{

    // 里面的代码永远仅仅运行1

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        _instance = [super allocWithZone:zone];

    });

    

    // 返回对象

    return _instance;

}


+ (instancetype)sharedAudioTool

{

    // 里面的代码永远仅仅运行1

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        _instance = [[self alloc] init];

    });

    

    // 返回对象

    return _instance;

}


+ (id)copyWithZone:(struct _NSZone *)zone

{

    return _instance;

}


@end



那么在MRC中呢?那当然就要考虑内存的释放了;必需要release了。

然而在release方法中,会调用[super release];

还有autorelease,retain,retainCount,copyWithZone;都得保证调用一次。

代码例如以下:


@interface HPAudioTool()

@end


@implementation HPAudioTool

//// 定义一份变量(整个程序执行过程中, 仅仅有1)

static id _instance;


- (id)init

{

    if (self = [super init]) {

        static dispatch_once_t onceToken;

        dispatch_once(&onceToken, ^{

            // 载入资源

            

        });

    }

    return self;

}

/**

 *  重写这种方法 : 控制内存内存

 */

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

{

    // 里面的代码永远仅仅运行1

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        _instance = [super allocWithZone:zone];

    });

    

    // 返回对象

    return _instance;

}


+ (instancetype)sharedAudioTool

{

    // 里面的代码永远仅仅运行1

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        _instance = [[self alloc] init];

    });

    

    // 返回对象

    return _instance;

}


+ (id)copyWithZone:(struct _NSZone *)zone

{

    return _instance;

}

- (oneway void)release

{

    

}


- (id)autorelease

{

    return _instance;

}


- (id)retain

{

    return _instance;

}


- (NSUInteger)retainCount

{

    return 1;

}


+ (id)copyWithZone:(struct _NSZone *)zone

{

    return _instance;

}

@end



当然我们在使用过程中。我们能够把这些代码写成宏,使用起来方便,便于改动。

为了兼容ARCMRC,我们能够将代码合并例如以下:


// ## : 连接字符串和參数

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


#if __has_feature(objc_arc) // ARC


#define singleton_m(name) \

static id _instance; \

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

{ \

static dispatch_once_t onceToken; \

dispatch_once(&onceToken, ^{ \

_instance = [super allocWithZone:zone]; \

}); \

return _instance; \

} \

\

+ (instancetype)shared##name \

{ \

static dispatch_once_t onceToken; \

dispatch_once(&onceToken, ^{ \

_instance = [[self alloc] init]; \

})\

return _instance; \

} \

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

{ \

return _instance; \

}


#else // ARC


#define singleton_m(name) \

static id _instance; \

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

{ \

static dispatch_once_t onceToken; \

dispatch_once(&onceToken, ^{ \

_instance = [super allocWithZone:zone]; \

}); \

return _instance; \

} \

\

+ (instancetype)shared##name \

{ \

static dispatch_once_t onceToken; \

dispatch_once(&onceToken, ^{ \

_instance = [[self alloc] init]; \

}); \

return _instance; \

} \

\

- (oneway void)release \

{ \

\

} \

\

- (id)autorelease \

{ \

return _instance; \

} \

\

- (id)retain \

{ \

return _instance; \

} \

\

- (NSUInteger)retainCount \

{ \

return 1; \

} \

\

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

{ \

return _instance; \

}


#endif

然后大家直接能够拷贝走,直接拿去调用。


posted on 2017-05-12 09:29  yjbjingcha  阅读(254)  评论(0编辑  收藏  举报

导航