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

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


  • 相关阅读:
    listview item 动画
    android sqlite blob
    Python3 配置文件(configparser)(转载)
    python之字符串格式化(format)
    PHP模拟发送POST请求之一、HTTP协议头部解析
    用HTML/JS/PHP方式实现页面延时跳转
    用memoization优化递归算法[JS/PHP实现]
    开通博客,记录一下。
    SpringMvc Json LocalDateTime 互转,form urlencoded @ModelAttribute 转换
    Springdata mongodb 版本兼容 引起 Error [The 'cursor' option is required, except for aggregate with the explain argument
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/6843995.html
Copyright © 2011-2022 走看看