iOS开发之单例设计模式(完整正确版本)

  单例的意思从字面上就可以略知一二,所谓单例就是确保在程序运行过程中只创建一个对象实例。可以用于需要被多次广泛或者说多次使用的资源中,比如我们常见的网络请求类、工具类以及其它管理类等。比如我iOS开发中常见的系统单例[UIApplication sharedApplication]、[NSUserDefaults  standardUserDefaults]等。在iOS开发中,单例模式是非常有用的一种设计模式。如下图,是一个简单的例模式的UML类图。

一、使用单例模式的作用

它可以保证某个类在程序运行过程中最多只有一个实例,也就是对象实例只占用一份内存资源。

二、单例模式的三个要点:

  1. 该类有且只有一个实例;

  2. 该类必须能够自行创建这个实例;

  3. 该类必须能够自行向整个系统提供这个实例。

三、为什么需要使用单例

  1.节省内存开销。如果某个对象需要被多个其它对象使用,那可以考虑使用单例,因为这样该类只使用一份内存资源。

  2.使用单例,可以确保其它类只获取类的一份数据(变量值)。

四、单例模式优缺点

优点

  1、提供了对唯一实例的受控访问。

  2、由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系统的性能。

  3.因为单例模式的类控制了实例化的过程,所以类可以更加灵活修改实例化过程。

缺点

  1、由于单利模式中没有抽象层,因此单例类的扩展有很大的困难。

  2、单例类的职责过重,在一定程度上违背了“单一职责原则”。

五、单例的实现

基本步骤:

  (1) 为单例对象创建一个静态实例,可以写成全局的,也可以在类方法里面实现,并初始化为nil;

  (2) 实现一个实例构造方法,检查上面声明的静态实例是否为nil,如果是,则创建并返回一个本类的实例;

  (3) 重写allocWithZone方法,用来保证其他人直接使用alloc和init试图获得一个新实力的时候不产生一个新实例;

  (4) 适当实现copyWithZone,mutableCopyWithZone,非arc下还需要实现release和autorelease方法。

下面我们来新建一个Singleton类,在Singleton.h中实现如下:

@interface Singleton : NSObject  

+ (Singleton *) sharedInstance;  

@end 

在Singleton.m添加如下内容:

@implementation Singleton  

static Singleton * sharedSingleton = nil;  

+ (Singleton *) sharedInstance
{
    if (sharedSingleton == nil) {
        sharedSingleton = [[Singleton alloc] init];
    }
    return sharedSingleton;
}  

@end  

  这样就创建一个简单的单例模式,实际上有一部分程序员也是这样实现的,但实际上这是一个不“严格”版本,在实际中使用,如果我们使用alloc,copy等方法创建对象时,依然会创建新的实例。而且如果多线程同时访问时候也会创建多个实例,因此这样做是非线程安全的。

下面我对Singleton.m的进行改进:

@implementation Singleton
static id sharedSingleton = nil;
+ (id)allocWithZone:(struct _NSZone *)zone
{
  if (_instace == nil) {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    sharedSingleton = [super allocWithZone:zone];
    });
  }
  return sharedSingleton;
} 

- (id)init
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    sharedSingleton = [super init];
    });
    return sharedSingleton;
} 

+ (instancetype)sharedInstance
{   return [[self alloc] init]; }

+ (id)copyWithZone:(struct _NSZone *)zone{     return sharedSingleton; } + (id)mutableCopyWithZone:(struct _NSZone *)zone {     return sharedSingleton; }@end

  这是一个比较完整的单例实现,这样在我们init,alloc,copy,mutableCopy时,都能保证只创建唯一单例。

六、把单例抽取成宏

  有时候我们一个程序会有多个单例,如果我们每个都去是有上面的代码,未免有些麻烦,因此我们可以讲上面的代码定义为宏,并保存在一个新文件中,然后就可以再任何需要实现单例模式的类中简单添加一两行代码就可以了。

  1.创建一个头文件Singleton.h,并添加如下代码:

// 帮助实现单例设计模式

// .h文件的实现
#define SingletonH(methodName) + (instancetype)shared##methodName;

// .m文件的实现
#if __has_feature(objc_arc) // 是ARC
#define SingletonM(methodName) static id _instace = nil; + (id)allocWithZone:(struct _NSZone *)zone { if (_instace == nil) { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instace = [super allocWithZone:zone]; }); } return _instace; } - (id)init { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instace = [super init]; }); return _instace; } + (instancetype)shared##methodName { return [[self alloc] init]; } + (id)copyWithZone:(struct _NSZone *)zone { return _instace; } + (id)mutableCopyWithZone:(struct _NSZone *)zone { return _instace; }

#else // 不是ARC

#define SingletonM(methodName) static id _instace = nil; + (id)allocWithZone:(struct _NSZone *)zone { if (_instace == nil) { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instace = [super allocWithZone:zone]; }); } return _instace; } - (id)init { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instace = [super init]; }); return _instace; } + (instancetype)shared##methodName { return [[self alloc] init]; } - (oneway void)release { } - (id)retain { return self; } - (NSUInteger)retainCount { return 1; } + (id)copyWithZone:(struct _NSZone *)zone {     return _instace; }  + (id)mutableCopyWithZone:(struct _NSZone *)zone {     return _instace; }

  2.这样我们在需要实现单例模式的类中轻易就可以实现单例模式了,假设有个工具类MJSoundTool。因此就可以这么做实现单例模式。

头文件MJSoundTool.h

#import <Foundation/Foundation.h>

#import "Singleton.h"

@interface MJSoundTool : NSObject

//+ (instancetype)sharedSoundTool;

SingletonH(SoundTool)

@end

实现文件MJSoundTool.m

#import "MJSoundTool.h"

@implementation MJSoundTool

SingletonM(SoundTool)

@end

  是不是很方便呢,我们以后需要设计单例的时候就可以直接使用该单例宏文件了。下载地址:单例宏Singleton.h。好了,单例模式就介绍到这里。??

时间: 2024-10-13 18:23:29

iOS开发之单例设计模式(完整正确版本)的相关文章

IOS开发之单例设计模式

本文将从四个方面对IOS开发中的单例设计模式进行讲解: 一.什么是单例设计模式 二.我们为什么要用单例设计模式 三.单例设计模式的基本用法 四.自定义单例设计模式代码的封装 一.什么是单例设计模式 所谓单例,即是单个的实例化对象,保证一个类有且仅有一个实例.通常情况下,当我们对一个类实例化时(如:alloc.new等),并不能保证每次实例化的对象是唯一的实例.那么为了保证该类可在多次实例化的过程中保证内存地址不变,就需要引入单例设计模式. 二.我们为什么要用单例设计模式 1.Singleton

IOS开发模式——单例

单例的模式在网上有很多,今天发下我个人对单例模式的理解.整个app中只存在一个实例,也只会进行一次实例,在实例完成之后是不可以人释放的(当App关闭之后,等系统自己回收). 也就是说,如果我们写得某个类符合了上述条件,那么我们也可以称这个类为单例. 在非ARC的工程中,我们需要针对alloc,retain,copy等会增加retaincount的参数加以控制,对release和autorelease等减少retailcount的操作增加控制,以确保单一实例,绝不释放. 在ARC的工厂中,由于,内

IOS中的单例设计模式

单例设计模式是IOS开发中一种很重要很常用的一种设计模式.它的设计原理是无论请求多少次,始终返回一个实例,也就是一个类只有一个实例.下面是苹果官方文档中关于单例模式的图片: 如图所示,左边的图是默认的多例模式,只要发送请求去创建对象,就会得到一个新的对象:而右侧的图是单例模式,发送多个请求创建对象,但是最后返回的始终是同一个. 因为创建单例类的实例是在确保没有其他实例的情况下才创建的,并且在程序中使用的过程中始终是同一个实例,因此单例类可以作为提供一个全局访问资源的类,比如NSUserDefau

iOS 中的单例设计模式

单例设计模式:在它的核心结构中只包含一个被称为单例类的特殊类.例如文件管理中的NSUserDefault,应用程序中的UIApplication,整个应用程序就这一个单例类,负责应用程序的一些操作,单例在那个文件下都能取得到. 通过单例设计模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节省系统资源.如果希望在系统中某个类的对象只能存在一个,单例模式是最好的选择. 下面来点实在的,创建单例代码上 方法1:基于线程安全创建一个单例 .h做一下声明 + (id)

iOS开发之单例头文件

// 帮助实现单例设计模式 // .h文件的实现 #define SingletonH(methodName) + (instancetype)shared##methodName; // .m文件的实现 #if __has_feature(objc_arc) // 是ARC #define SingletonM(methodName) static id _instace = nil; + (id)allocWithZone:(struct _NSZone *)zone { if (_inst

iOS开发之——单例的几种设计方式

单例是ios开发中常用的一种设计模式,通常用来控制器之间传值.方便.高效,全局通用. 单例模式的设计分为ARC和MRC. ARC: 方式一 1.创建一个继承自NSObject的类. 2.在这个类的.h文件中声明类方法: + (instancetype)sharedInstance; 2.在这个类的.m文件中实现以下方法: static id instance; + (instancetype)sharedInstance { static dispatch_once_t onceToken; d

iOS开发-一些单例的类

UIApplication(应用程序实例) NSNotificationCenter(消息中心)  NSFileManager(文件管理)    NSUserDefaults(应用程序设置)     NSURLCache(请求缓存)   NSHTTPCookieStorage(应用程序cookies池)

iOS开发设计模式之单例设计模式

单例设计模式 是一种常用的软件设计模式,保证系统中的一个类只有一个实例而且该实例易于被外界访问. 单例的英文:singleton,在数学中的含义是:有且仅有一个元素的集合. 如果希望系统中某个类的对象只能存在一个,单例模式是最好的解决方案 优点: 可以阻止其他对象实例化对象的副本,从而确保所有对象都访问唯一实例 缺点: 单例对象一旦创建,对象指针保存在全局静态区,而单例对象在堆中分配内存空间,在应用程序终止后才会被释放 使用到单例设计模式的类:(大部分用于管理系统的资源) UIApplicati

iOS常用设计模式——单例设计模式

单例设计模式详解 单例设计模式详解 基本概念 在IOS中使用单例模式的情况 非ARC环境创建单例模式的基本步骤 非ARC环境具体代码实现 ARC环境创建单例模式的基本步骤 基本概念 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问 在IOS中使用单例模式的情况 1.如果说创建一个对象会耗费很多系统资源,那么此时采用单例模式,因为只需要一个实例,会节省alloc的时间 2.在IOS开发中,如果很多模