iOS 单例模式
2016-07-19 17:45
471 查看
1. 单例模式的作用
可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问从而方便地控制了实例个数,并节约系统资源2. 单例模式的使用场合
在整个应用程序中,共享一份资源(这份资源只需要创建初始化1次)为防止单例模式滥用,下面几种情况可以不使用单例:仅仅使用一次的模块,可以不使用单例,可以采用在对应的周期内维护成员实例变量进行替换。和状态无关的模块,可以采用静态(类)方法直接替换。可以通过页面跳转进行依赖注入的模块,可以采用依赖注入或者变量传递等方式解决3. ARC中,单例模式的实现
1.在.m中保留一个全局的static的实例static id _instance;2.重写allocWithZone:方法,在这里创建唯一的实例使用dispatch_once 实现线程安全重写allocWithZone是为了使用 [ClassallocWithZone:nil]实例化对象时依旧只创建唯一实例
+ (instancetype)allocWithZone:(struct _NSZone *)zone { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [super allocWithZone:zone]; }); return _instance; }3.提供1个类方法让外界访问唯一的实例
+ (instancetype)sharedInstance { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [[self alloc] init]; }); return _instance; }4.实现copyWithZone:方法
- (id)copyWithZone:(struct _NSZone *)zone { return _instance; }
4.ARC中完整版(GCD)
static id _instance; + (instancetype)allocWithZone:(struct _NSZone *)zone { static dispatch_once_t onceToken; // 必须是静态的 dispatch_once(&onceToken, ^{ _instance = [[super allocWithZone:zone] init]; // 记住这儿是super,不能用self }); return _instance; } + (instancetype)sharedPerson { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [[self alloc] init]; }); return _instance; } // copyWithZone方法的前提是必须先有一个对象 - (id)copyWithZone:(NSZone *)zone { return _instance; }[/code]在实际开发中,一个应用程序可能有多个对象是单例对象,此时我们应该把
单例抽成一个宏放在一个单独的.h文件中,
千万不能用继承其中
\表示此行跟下面一行是一起的
##表示后面是参数此时,注释只能在上面,在右边注释会报错的
// .h文件中的声明 #define SLInstanceH(name) + (instancetype)shared##name; // .m文件的实现 #define SLInstanceM(name) static id _instance; \ \ + (instancetype)allocWithZone:(struct _NSZone *)zone\ {\ static dispatch_once_t onceToken;\ dispatch_once(&onceToken, ^{\ _instance = [[super allocWithZone:zone] init];\ });\ return _instance;\ }\ \ + (instancetype)shared##name\ {\ static dispatch_once_t onceToken;\ dispatch_once(&onceToken, ^{\ _instance = [[self alloc] init];\ });\ return _instance;\ }\ \ - (id)copyWithZone:(NSZone *)zone\ {\ return _instance;\ }[/code]使用宏的时候在.m文件中
#import <Foundation/Foundation.h> #import "SLSharedInstance.h" // 导入,定义了宏的.h文件 @interface SLPerson : NSObject<NSCopying> SLInstanceH(Person) // 传入单例的对象 @end在.h文件中
#import "SLPerson.h" @implementation SLPerson SLInstanceM(Person) @end
5. 单例模式(常规做法,非GCD)
一定要加互斥锁,不然会有线程安全问题#import "SLPerson.h" @implementation SLPerson static id _instance; + (instancetype)allocWithZone:(struct _NSZone *)zone { @synchronized(self){ // 一定要加互斥锁,不然会有线程安全问题 if (_instance == nil) { _instance = [[super allocWithZone:zone] init]; } } return _instance; } + (instancetype)sharedPerson { @synchronized(self){ if (_instance == nil) { _instance = [[self alloc] init]; } } return _instance; } // 要有对象才能进行copy - (id)copyWithZone:(NSZone *)zone { return _instance; } @end单例模式的参考内容:
滥用单例之dispatch_once死锁 http://satanwoo.github.io/
从 Objective-C 里的 Alloc 和 AllocWithZone 谈起 http://justinyan.me/post/1306
Objective-C中单例模式的实现http://cocoa.venj.me/blog/singleton-in-objc/相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 交换机升级排障实例
- sql2008启动代理未将对象应用到实例解决方案
- 举例讲解C#编程中对设计模式中的单例模式的运用
- php设计模式之单例模式实例分析
- PHP基于单例模式实现的数据库操作基类
- JavaScript编程的单例设计模讲解
- Ajax教程实例详解
- C#设计模式之单例模式实例讲解
- Javascript实现单例模式
- JS模式之单例模式基本用法
- 深入理解JavaScript系列(25):设计模式之单例模式详解
- 初识JQuery 实例一(first)
- JQuery入门基础小实例(1)