美文网首页
单例模式(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