美文网首页iOS开发技术Flutter
iOS设计模式-----单例模式

iOS设计模式-----单例模式

作者: HHHHHHHHHHD | 来源:发表于2015-10-15 11:58 被阅读2410次
    单例模式

    这个单例模式的写法是参照MJ哥的写法。追求最精简。
    1.只分配一块内存来创建对象。
    2.提供一个类方法,返回内部唯一的一个对象。
    3.最好保证init方法也是只初始化一次。

    单例模式的目的

    1.可以保证App在程序运行中,一个类只有唯一个实例,从而做到节约内存。
    2.在整个App程序中,这一份资源是共享的。
    3.提供一个固定的实例创建方法。

    单例模式在ARC\MRC环境下的写法是不相同的,所以需要两份代码。

    在这里,我是看到MJ哥视频后,发现单利模式结合宏,超级方便。

    #if __has_feature(objc_arc)
    // ARC
    #else
    // MRC
    #endif
    

    下面先来看下单利模式不结合宏的写法

    /**
     *  数据只初始化一次
     */
    
    static id _instace;
    //- (instancetype)init
    //{
    //    static id object = nil;
    //    static dispatch_once_t onceToken;
    //    dispatch_once(&onceToken, ^{
    //        
    //        if (((object = [super init]) !=nil)) {
    //            
    //            //加载所需要的资源
    //            
    //        }
    //    });
    //    self = object;
    //    return self;
    //}
    
    - (instancetype)init
    {
        self = [super init];//如果单利是有继承的话,则需要考虑init方法也是只需要加载一次。则用上面的方法。
        if (self) {
            
            static dispatch_once_t onceToken;
            dispatch_once(&onceToken, ^{
                
                //加载所需要的音频资源
                
            });
        }
        return self;
    }
    /**
     *  重写这个方法是为了控制内存。只分配一份内存。
     */
    +(id)allocWithZone:(struct _NSZone *)zone{
    
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _instace = [super allocWithZone:zone];
        });
        return _instace;
    }
    
    /**
     *  提供给外部的方法
     */
    +(instancetype)sharedSingleTon{
    
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _instace = [[self alloc]init];
        });
        
        return _instace;
    }
    

    非ARC时候要手动释放内存所以要写内存管理方法。就是在ARC的代码下添加多内存管理方法。

    /**
     *  数据只初始化一次
     */
    
    static id _instace;
    //- (instancetype)init
    //{
    //    static id object = nil;
    //    static dispatch_once_t onceToken;
    //    dispatch_once(&onceToken, ^{
    //        
    //        if (((object = [super init]) !=nil)) {
    //            
    //            //加载所需要的资源
    //            
    //        }
    //    });
    //    self = object;
    //    return self;
    //}
    
    - (instancetype)init
    {
        self = [super init];//如果单利是有继承的话,则需要考虑init方法也是只需要加载一次。则用上面的方法。
        if (self) {
            
            static dispatch_once_t onceToken;
            dispatch_once(&onceToken, ^{
                
                //加载所需要的音频资源
                
            });
        }
        return self;
    }
    /**
     *  重写这个方法是为了控制内存。只分配一份内存。
     */
    +(id)allocWithZone:(struct _NSZone *)zone{
    
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _instace = [super allocWithZone:zone];
        });
        return _instace;
    }
    
    /**
     *  提供给外部的方法
     */
    +(instancetype)sharedSingleTon{
    
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _instace = [[self alloc]init];
        });
        
        return _instace;
    }
    //实现内存管理方法
    - (id)retain{
        return self;
    }
    - (NSUInteger)retainCount{
        return 1;
    }
    - (oneway void)release{
    }
    - (id)autorelease{
        return self;
    }
    

    下面是单利模式结合宏简直好用到爆炸,代码精简
    宏方法

    
    // ## : 连接字符串和参数
    #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; \
    }
    
    #else// MRC时候调用的单例模式
    
    #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
    
    
    
    

    单例.h文件

    
    #import <Foundation/Foundation.h>
    #import "Singleton.h"
    @interface SingletonCode : NSObject
    /**
     *  这个就是宏创建的类方法
     */
    Singleton_h(TextSingleton);
    @end
    

    单例.m文件

    #import "SingletonCode.h"
    @implementation SingletonCode
    
    - (instancetype)init
    {
        self = [super init];
        if (self) {
            
            static dispatch_once_t onceToken;
            dispatch_once(&onceToken, ^{
                
                //加载所需要的资源文件
                
            });
        }
        return self;
    }
    /**
     *  这个就是宏实现的类方法
     */
    Singleton_m(TextSingleton);
    
    @end
    

    相关文章

      网友评论

      • 217f420bfc40:类至少都会有继承NSObject吧 ?? 所以是不是都要写成static id obeect = nil 的形式呢??
      • 217f420bfc40:在什么情境下需要两种单利模式都要写?
      • 我是小文:分享下源码嘛
      • 小小猿:真的很棒
      • 546055050dc0:看不太懂,如果结合使用情景解释下就好了...
        546055050dc0:@像孩子一样 就是实际项目中,单例使用在哪里,为什么要用单例
        HHHHHHHHHHD:@EXALEX 单例不明白还是?

      本文标题:iOS设计模式-----单例模式

      本文链接:https://www.haomeiwen.com/subject/ukwocttx.html