OC-单例模式

文章目录

单例模式

定义

单例模式,简单的说就是一个类始终只对应同一个对象,每次获取这个类的对象获得的都是同一个实例

如果一个类始终只能创建一个实例,那么这个类被称为单例类。单例类只有一个全局的接口来访问这个实例。当第一次载入的时候,他通常使用延迟加载的方创建唯一单例。在程序中一个单例只初始化一次,为了保证在使用中始终存在,单例类的存储是在存储器的全局区域,在编译时分配内存,只要程序在运行单例就始终存在,占用内存。在APP结束运行后释放这部分内存。但是在系统方法中,存在未知的自动释放池,如果对一个对象进行自动释放的话,可能进入未知的释放池,出现内存问题。即为单例模式不能自动释放的原因

特点

  1. 单例类是一个类,这个类创造出的对象是单例对象
  2. 单例对象使用类方法创建
  3. 单例一旦被创建出来,直到程序结束运行才会释放
  4. 单例不用我们来管理内存,内存会随着程序关闭而被释放

使用原因

节省内存,防止一个实例被重复创建从而占用内存空间。

缺点

  • 全局状态:可能导致全局状态的存在,使得程序难以调试,一个地方修改容易导致很多地方发生变化
  • 难以拓展:单例模式的实例是固定的,难以拓展以支持多个实例,必须修改代码,使单例类丢失单例的特性
  • 隐藏依赖关系:可能会隐藏单例类的依赖关系,代码更加耦合。

模式介绍

懒汉模式

是一种常见的单例设计模式,其主要特点是在需要时在创建单例对象的实现,通过延迟对象的初始化来节省资源和提高性能。适用于访问量较小的情况,使用时间来换取空间

同步锁实现
objectivec 复制代码
#import "Person.h"

@implementation Person
static id instance = nil;
+ (instancetype)sharedInstance {
    @synchronized (self) {
        if (!instance) {
            instance = [[super allocWithZone:NULL] init];
        }
    }
    return instance;
}
@end

这一段代码提供了一个全局访问点sharedInstace类方法提供给外部访问这个单例,在方法内部通过添加了一个同步锁,限制了同一时间只有一个线程访问临界区的代码。但是这里如果instance已经存在是没有必要进入锁的,所以可以再加个判断如下:

objectivec 复制代码
#import "Person.h"

@implementation Person
static id instance = nil;
+ (instancetype)sharedInstance {
    if (!instance) {
        @synchronized (self) {
            if (!instance) {
                instance = [[super allocWithZone:NULL] init];
            }
        }
    }
    return instance;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    if (!instance) {
        @synchronized (self) {
            if (!instance) {
                instance = [super allocWithZone:zone];
            }
        }
    }
    return instance;
}

- (id)copyWithZone:(NSZone *)zone {
    return self;
}

- (id)mutableCopyWithZone:(NSZone *)zone {
    return self;
}
@end

对于allocWithZone的参数,传什么其实都无所谓,分配的内存区域不会改变

内层if的作用:假设有两个线程A和B同时调用了sharedInstance,线程A先一步获取锁,进入代码块,此时线程B等待锁释放,当线程A初始化instance后释放锁,B获得锁,如果没有内层if判断,会再次创建实例,破坏了单例的唯一性

dispatch_once

通过一个静态的dispatch_once变量来跟踪代码的执行状态,第一次调用时原子操作发现标记状态为未执行代码块,并原子性的将标记设为已执行,后续监测到标记为已执行,就会跳过该代码块。非常高效、没有阻塞开销

objectivec 复制代码
#import "Person.h"

@implementation Person
static id instance = nil;
+ (instancetype)sharedInstance {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[super allocWithZone:NULL] init];
    });
    return instance;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [super allocWithZone:zone];
    });
    return instance;
}

- (id)copyWithZone:(NSZone *)zone {
    return self;
}

- (id)mutableCopyWithZone:(NSZone *)zone {
    return self;
}
@end

我们打印出不同情况下的对象地址如下:

饿汉模式

在类加载过程就完成这个单例的创建和初始化

实现
objectivec 复制代码
#import "Person.h"

@implementation Person
static id instance = nil;

+ (void)load {
    instance = [[super allocWithZone:NULL] init];
}

+ (instancetype)sharedInstance {
    return instance;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    return instance;
}

- (instancetype)init {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSLog(@"init一次");
    });
    return self;
}

- (id)copyWithZone:(NSZone *)zone {
    return self;
}

- (id)mutableCopyWithZone:(NSZone *)zone {
    return self;
}

@end

总结

懒汉模式

优点
  1. 延迟加载,节省资源,提高性能。
  2. 避免在程序启动时就创造不必要的对象,造成额外开销
  3. 可以通过加锁实现线程安全
缺点
  1. 为实现线程安全使用锁机制,可能会引起一些性能开销

饿汉模式

优点
  1. 实现简单,不需要考虑线程安全问题,实例在类加载时就已经创建了,所以不用考虑创建多个实例的风险
缺点
  1. 程序启动时就加载创建实例,可能会浪费资源,引起性能问题
  2. 如果单例对象的创建需要建立在某些外部前提下,那么不适合饿汉模式
相关推荐
醉、倾城1 小时前
面向开发人员的macOS入门教程
macos·策略模式
2501_9160137411 小时前
iOS 26 系统流畅度检测 从视觉特效到帧率稳定的实战策略
android·macos·ios·小程序·uni-app·cocoa·iphone
游戏开发爱好者820 小时前
iOS 26 崩溃日志深度解读,获取方式、系统变动、定位策略
android·macos·ios·小程序·uni-app·cocoa·iphone
StrongerIrene1 天前
mac 安装npm之后,其他终端无法访问
macos
深盾科技1 天前
如何读懂Mach-O:构建macOS和iOS应用安全的第一道认知防线
安全·macos·ios
FreeBuf_1 天前
iOS 0Day漏洞CVE-2025-24085相关PoC利用细节已公开
macos·ios·cocoa
壕壕1 天前
Re: 0x02. 从零开始的光线追踪实现-射线跟球的相交
macos·计算机图形学
林鸿群1 天前
MacOS arm64 编译GStreamer iOS平台库
macos·ios
hi啦克1 天前
macOS 下安装 zsh、zsh-syntax-highlighting、powerlevel9k、nerd-font
macos·zsh·语法高亮·powerlevel9k·nerd-font
Blue桃之夭夭1 天前
WebStorm 快捷键大全(Windows / macOS 双平台对照)
windows·macos·webstorm