优才网站建设,简单网页制作html,微信公众号排版编辑,山西人工智能建站系统软件文章目录 前言一、单例模式简介二、单例模式优缺点优点缺点 三、模式介绍1.懒汉模式2. 饿汉模式 总结 前言
在最初进行OC的学习时笔者了解过单例模式的基本使用#xff0c;现撰写博客加深对单例模式的理解 一、单例模式简介
单例模式是一种常见的设计模式#xff0c;其主要… 文章目录 前言一、单例模式简介二、单例模式优缺点优点缺点 三、模式介绍1.懒汉模式2. 饿汉模式 总结 前言
在最初进行OC的学习时笔者了解过单例模式的基本使用现撰写博客加深对单例模式的理解 一、单例模式简介
单例模式是一种常见的设计模式其主要目的是确保一个类只有一个实例并提供全局访问点。这样就大大节省了我们的内存防止一个实例被重复创建从而占用内存空间。这种模式在需要一个共享资源或对象的情况下非常有用但也有一些优点和缺点。 面向对象应用程序中的单例类singleton class总是返回自己的同一个实例。它提供了对象所提供的资源的全局访问点。与这类设计相关的设计模式称为单例模式。 大家在开发过程中也见过不少的单例比如UIApplication、UIAccelerometer重力加速、NSUserDefaults、NSNotificationCenter当然这些是开发Cocoa Touch框架中的在Cocoa框架中还有NSFileManager、NSBundle等。 二、单例模式优缺点
优点
一个类只被实例化一次提供了对唯一实例的受控访问节省系统资源允许可变数目的实例
缺点
全局状态单例模式可能导致全局状态的存在这使得程序更难调试和理解。全局状态的改变可能会影响多个部分增加了代码的复杂性。难以扩展由于单例模式的实例是固定的因此很难扩展以支持多个实例。如果需要多个实例必须修改代码将单例模式改为允许多个实例。隐藏依赖关系使用单例模式的代码可能会隐藏对单例类的依赖关系这使得代码更加耦合。这可能使单元测试和模块化难以实现。不适用于多线程环境在多线程环境下需要特殊的处理来确保单例模式的线程安全性。否则可能会出现多个实例被创建的情况。
三、模式介绍
1.懒汉模式
懒汉模式Lazy Initialization是一种常见的单例设计模式其主要特点是在需要时才会创建单例对象的实例而不是在程序启动时就立即创建。懒汉模式通过延迟对象的初始化来节省资源和提高性能。
举个简单的例子你现在有衣服要洗但是可以选择先不洗等没衣服穿的时候再洗这就是懒汉模式的逻辑——需要用到实例时再去创建实例。 我们给出懒汉模式的代码
ViewController.h
#import UIKit/UIKit.hinterface ViewController : UIViewControllerNSCopying, NSMutableCopying(instancetype)shareSingleton;endViewController.m
#import ViewController.hinterface ViewController ()endimplementation ViewControllerstatic id _instance; (instancetype)allocWithZone:(struct _NSZone *)zone {if (_instance nil) {//互斥锁防止被频繁加锁synchronized (self) {if (_instance nil) {//防止单例被多次创建_instance [super allocWithZone:zone];}}}return _instance;
} (instancetype)shareSingleton {if (_instance nil) { //防止被频繁枷锁synchronized (self) {if (_instance nil) {_instance [[self alloc] init];}}}return _instance;
}- (void)viewDidLoad {[super viewDidLoad];_instance [[NSString alloc] init];_instance 111;NSLog(%, _instance);
}- (nonnull id)copyWithZone:(nullable NSZone *)zone {return _instance;
}- (nonnull id)mutableCopyWithZone:(nullable NSZone *)zone {return _instance;
}
//copyWithZone: 和 mutableCopyWithZone: 方法是用于复制对象的方法。在这里它们都被重写为返回单例对象的引用 _instance以确保复制操作也得到同一个单例对象的引用而不会创建新的对象副本。end使用懒汉模式时我们有几个问题值得我们讨论
这样创建单例是否可以 (instancetype)allocWithZone:(struct _NSZone *)zone {if (_instance nil) {//互斥锁防止被频繁加锁synchronized (self) {_instance [super allocWithZone:zone];}}return _instance;
}答案是不行的因为我们只是锁住了对象的创建如果两个线程同时进入if那么就会产生两个对象
为什么要用static修饰单例
如果我们不使用static其他类中可以使用extern来拿到这个单例
extern id instance;
instance nil;如果在其他类中对单例进行如下操作那么单例就会被重新创建我们原本的单例对象中的内容就被销毁了。
具体用法可以参考这篇博客【iOS】浅析staticconstextern关键字
allocWithZone 与copyWithZone方法
通过代码可以看到我们的allocWithZone与shareSingleton方法是相同的我们既可以通过shareSingleton创建单例也可以通过allocWithZone创建单例。
copyWithZone: 和 mutableCopyWithZone: 方法是用于复制对象的方法。在这里它们都被重写为返回单例对象的引用 _instance以确保复制操作也得到同一个单例对象的引用而不会创建新的对象副本。
2. 饿汉模式
在没有使用代码去创建对象之前这个对象已经加载好了并且分配了内存空间当你去使用代码创建的时候实际上只是将这个原本创建好的对象拿出来而已。
通俗的理解就是我们可以选择一回家就吃饭也可以选择回家后躺一会再吃躺一会再吃就是懒汉模式直接吃就是饿汉模式
在我们的类加载过程中我们的单例就已经被创建了我们无需在后面再去创建直接使用即可
这里给出代码示例
ehanViewController.h
#import UIKit/UIKit.hNS_ASSUME_NONNULL_BEGINinterface ehanViewController : UIViewControllerNSMutableCopying, NSCopying//获取单例(instancetype)sharedSingleton;endNS_ASSUME_NONNULL_END
ehanViewController.m
#import ehanViewController.hinterface ehanViewController ()endimplementation ehanViewControllerstatic id _instance;//当类加载到OC运行时环境中(内存)就会调用一次一个类之后加载一次(void)load {_instance [[self alloc] init];
} (instancetype)allocWithZone:(struct _NSZone *)zone {if (_instance nil) { //防止创建多次_instance [super allocWithZone:zone];}return _instance;
}(instancetype)sharedSingleton {return _instance;
}- (void)viewDidLoad {[super viewDidLoad];_instance 111;NSLog(%, _instance);
}- (nonnull id)copyWithZone:(nullable NSZone *)zone {return _instance;
}- (nonnull id)mutableCopyWithZone:(nullable NSZone *)zone {return _instance;
}end总结
懒汉模式
优点 延迟加载懒汉模式只有在第一次访问单例实例时才会进行初始化可以节省资源提高性能因为实例只有在需要时才会被创建。 节省内存如果单例对象很大或者初始化过程开销较大懒汉模式可以避免在程序启动时就创建不必要的对象。 线程安全性可以通过加锁机制如双重检查锁定来实现线程安全。 缺点 线程安全性开销懒汉模式在实现线程安全时可能需要额外的同步机制这会引入一些性能开销。 复杂性增加实现线程安全的懒汉模式可能需要编写复杂的代码容易引入错误。缺点 线程安全性开销懒汉模式在实现线程安全时可能需要额外的同步机制这会引入一些性能开销。 复杂性增加实现线程安全的懒汉模式可能需要编写复杂的代码容易引入错误。
饿汉模式
优点 简单饿汉模式实现简单不需要考虑线程安全问题因为实例在类加载时就已经创建。 线程安全性由于实例在类加载时创建不会存在多个实例的风险因此线程安全。缺点 无法实现延迟加载饿汉模式在程序启动时就创建实例无法实现延迟加载可能会浪费资源特别是当实例很大或初始化开销较大时。 可能引起性能问题如果单例类的实例在程序启动时没有被使用那么创建实例的开销可能是不必要的。 不适用于某些情况如果单例对象的创建依赖于某些外部因素而这些因素在程序启动时无法确定那么饿汉模式可能不适用。
总的来说懒汉模式适用于需要延迟加载实例的情况可以节省资源和提高性能但需要考虑线程安全性。饿汉模式适用于需要简单实现和线程安全性的情况但不支持延迟加载。选择哪种模式应根据具体需求和性能考虑来决定。