zoukankan      html  css  js  c++  java
  • 单例模式


    单例模式 - GCD 、兼容ARCMRC



    单例模式的作用:

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

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


    单例模式的使用场合:

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


    单例模式在ARCMRC环境下的写法有所不同。须要编写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

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


  • 相关阅读:
    URL 转化为 Dictionary 字典
    ios 续费 问题 冰山一角
    1.node.js在遇到“循环+异步”时的注意事项
    1.【微信小程序经验】各类图表相关组件+Demo源码(折线图,柱状图,K线,分时图)
    10. 启动WPS for Linux后,出现提示"系统缺失字体"
    8.Postman中发送请求被拦截(证书问题)
    20.mysql查看sql执行时间
    19.Mysql索引结构及常见索引的区别
    18.mysql优化(三)–explain分析sql语句执行效率
    9.安装的第一个Linux系统 -Linux Mint 18.1 cinnamon
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/6843995.html
Copyright © 2011-2022 走看看