美文网首页
单例模式(Singleton Pattern)

单例模式(Singleton Pattern)

作者: long弟弟 | 来源:发表于2022-09-08 23:46 被阅读0次

    单例模式,单件模式

    意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

    一个类只允许创建一个对象(或者实例),那么这个类就是一个单例类,这种设计模式就叫作单例设计模式,简称单例模式。

    单例模式.jpg

    熟悉C++或Java的童鞋都知道单例模式有饿汉式和懒汉式两种。而OC是不支持饿汉式,因为静态常量不是编译时常量。
    一般常用的都是懒汉式,除了多线程外还要考虑的new、copy等情况

    代码示例

    方案一:宏定义

    single.h

    #define SingleH(name) + (instancetype)shared##name;
    
    #if __has_feature(objc_arc)
    //ARC
    #define SingleM(name) static id _instance;\
    + (instancetype)allocWithZone:(struct _NSZone *)zone {\
        static dispatch_once_t onceToken;\
        dispatch_once(&onceToken, ^{\
            _instance = [super allocWithZone:zone];\
        });\
        return _instance;\
    }\
    \
    + (instancetype)shared##name {\
        return [[self alloc]init];\
    }\
    \
    - (id)copyWithZone:(NSZone *)zone {\
        return _instance;\
    }\
    \
    - (id)mutableCopyWithZone:(NSZone *)zone {\
        return _instance;\
    }
    
    #else
    //MRC
    #define SingleM(name) static id _instance;\
    + (instancetype)allocWithZone:(struct _NSZone *)zone {\
        static dispatch_once_t onceToken;\
        dispatch_once(&onceToken, ^{\
            _instance = [super allocWithZone:zone];\
        });\
        return _instance;\
    }\
    \
    + (instancetype)shared##name {\
        return [[self alloc]init];\
    }\
    \
    - (id)copyWithZone:(NSZone *)zone {\
        return _instance;\
    }\
    \
    - (id)mutableCopyWithZone:(NSZone *)zone {\
        return _instance;\
    }\
    \
    - (oneway void)release {\
        \
    }\
    \
    - (instancetype)retain {\
        return _instance;\
    }\
    \
    - (NSUInteger)retainCount {\
        return MAXFLOAT;\
    }\
    \
    - (instancetype)autorelease {\
        return _instance;\
    }
    
    #endif
    

    main.m

    #import <Foundation/Foundation.h>
    #import "Single.h"
    @interface YQTest : NSObject
    SingleH(Tools)
    @end
    @implementation YQTest
    SingleM(Tools)
    @end
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            YQTest *s1 = [YQTest sharedTools];
            YQTest *s2 = [YQTest sharedTools];
            NSLog(@"%p-%p", s1, s2);
            //0x1006233e0-0x1006233e0
        }
        return 0;
    }
    

    方案二:声明禁用new、copy等方法

    #import <Foundation/Foundation.h>
    @interface YQNetworkTools : NSObject
    + (instancetype)shared;
    - (instancetype)init UNAVAILABLE_ATTRIBUTE;
    + (instancetype)new UNAVAILABLE_ATTRIBUTE;
    - (id)copy UNAVAILABLE_ATTRIBUTE;
    - (id)mutableCopy UNAVAILABLE_ATTRIBUTE;
    @end
    @implementation YQNetworkTools
    static YQNetworkTools *sharedInstance = nil;
    + (instancetype)shared {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            sharedInstance = [[self alloc]init];
        });
        return sharedInstance;
    }
    @end
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            YQNetworkTools *t1 = [YQNetworkTools shared];
            YQNetworkTools *t2 = [YQNetworkTools shared];
            NSLog(@"%p-%p", t1, t2);
            //0x1007179b0-0x1007179b0
            
            //YQNetworkTools *t3 = [[YQNetworkTools alloc] init];
            //YQNetworkTools *t4 = [YQNetworkTools new];
            //YQNetworkTools *t5 = [t1 copy];
            //YQNetworkTools *t6 = [t1 mutableCopy];
        }
        return 0;
    }
    

    用处

    从业务概念上,有些数据在系统中只应该保存一份,就比较适合设计为单例类,表示全局唯一类。比如系统的配置信息类,工具类等。

    iOS系统提供了很多单例的类UIApplicationNSUserDefaultsNSFileManagerNSURLCacheNSNull等等

    优点

    只会实例化一次,如果有问题能快速定位。只有一个对象,节省系统内存资源,提高运行效率。

    缺点

    1. 单例对OOP特性的支持不友好
      违背了基于接口而非实现编程
    2. 不易扩展或重写
      需求变更,开发中遇到问题
    3. 闲置消耗内存资源(一直存在)

    题外话

    iOS也可以实现多例模式,想要了解更多代理应用的童鞋可以自行学习了解一下。

    相关文章

      网友评论

          本文标题:单例模式(Singleton Pattern)

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