单例模式——使用GCD实现单例模式 & 非ARC单例模式 &使用GCD和线程锁实现单例模式-b
1.单利模式概述
链接: iOS开发懒汉模式&恶寒模式
2.使用GCD实现单利模式
2.1新建一个project,然后新建一个HMDataTool类展示GCD实现单例模式
- #import <Foundation/Foundation.h>
- @interface HMDataTool : NSObject
- + (instancetype)sharedDataTool;
- @end
- #import "HMDataTool.h"
- @implementation HMDataTool
- // 用来保存唯一的单例对象
- static id _instace;
- + (id)allocWithZone:(struct _NSZone *)zone
- {
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{ //onceToken是GCD用来记录是否执行过 ,如果已经执行过就不再执行(保证执行一次)
- _instace = [super allocWithZone:zone];
- });
- return _instace;
- }
- + (instancetype)sharedDataTool
- {
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- _instace = [[self alloc] init];
- });
- return _instace;
- }
- - (id)copyWithZone:(NSZone *)zone
- {
- return _instace;
- }
- @end
- #import "htingViewController.h"
- #import"HMDataTool.h"
- @interface htingViewController ()
- @end
- @implementation htingViewController
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- // Do any additional setup after loading the view, typically from a nib.
- HMDataTool *tool1 = [HMDataTool sharedDataTool];
- HMDataTool *tool2 = [HMDataTool sharedDataTool];
- HMDataTool *tool3 = [[HMDataTool alloc] init];
- HMDataTool *tool4 = [[HMDataTool alloc] init];
- NSLog(@"%@ %@ %@ %@", tool1, tool2, tool3, tool4);
- }
- @end
打印结果
- 使用GCD实现单利模式[2334:607] <HMDataTool: 0x8f064c0> <HMDataTool: 0x8f064c0> <HMDataTool: 0x8f064c0> <HMDataTool: 0x8f064c0>
3.非ARC实现单例模式
3.1非ARC内存管理模式下对象必须手动释放,为了防止那个唯一的单例对象被释放掉,则只需要重写下面的几个方法即可
- - (oneway void)release { }
- - (id)retain { return self; }
- - (NSUInteger)retainCount { return 1;}
- - (id)autorelease { return self;}
3.2通过新建一个HMDataTool类来演示非ARC单例模式
- // HMDataTool.h
- #import <Foundation/Foundation.h>
- @interface HMDataTool : NSObject
- + (instancetype)sharedDataTool;
- @end
- //
- // HMDataTool.m
- // 03-单例模式-Singleton(掌握)
- //
- // Created by apple on 14-9-16.
- // Copyright (c) 2014年 heima. All rights reserved.
- //
- #import "HMDataTool.h"
- @implementation HMDataTool
- // 用来保存唯一的单例对象
- static id _instace;
- + (id)allocWithZone:(struct _NSZone *)zone
- {
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- _instace = [super allocWithZone:zone];
- });
- return _instace;
- }
- + (instancetype)sharedDataTool
- {
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- _instace = [[self alloc] init];
- });
- return _instace;
- }
- - (id)copyWithZone:(NSZone *)zone
- {
- return _instace;
- }
- /**
- * 重写下面几个关于引用计数器的方法就可以防止修改引用计数器的值,
- 这样就可以这个对象永远停留在内存中(因为这几个方法都是空的,所以尽管怎么调用,都没有作用)
- *
- * @return <#return value description#>
- */
- - (oneway void)release { }
- - (id)retain { return self; }
- - (NSUInteger)retainCount { return 1;}
- - (id)autorelease { return self;}
- @end
- //
- // HMViewController.h
- #import <UIKit/UIKit.h>
- @interface HMViewController : UIViewController
- @end
- //
- // HMViewController.m
- #import "HMViewController.h"
- #import "HMDataTool.h"
- @interface HMViewController ()
- @end
- @implementation HMViewController
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- HMDataTool *tool1 = [[HMDataTool alloc] init];
- HMDataTool *tool2 = [[HMDataTool alloc] init];
- HMDataTool *tool3 = [HMDataTool sharedDataTool];
- HMDataTool *tool4 = [HMDataTool sharedDataTool];
- /**
- * 重写了下面几个方法之后,则随便释放N次都没有用了
- - (oneway void)release { }
- - (id)retain { return self; }
- - (NSUInteger)retainCount { return 1;}
- - (id)autorelease { return self;}
- */
- [tool4 autorelease];
- [tool4 autorelease];
- [tool4 autorelease];
- [tool4 autorelease];
- [tool4 autorelease];
- NSLog(@"%@ %@ %@ %@", tool1, tool2, tool3, tool4);
- }<pre name="code" class="objc">+(loginModel *)sharedloginModel
- {
- static loginModel *loginmodle = nil;
- @synchronized(self)
- {
- if (loginmodle == nil) {
- loginmodle = [[loginModel alloc] init];
- }
- }
- return loginmodle;
- }
@end
运行结果
单例模式-非ARC(掌握)[2592:607] <HMDataTool: 0x8d12600> <HMDataTool: 0x8d12600> <HMDataTool: 0x8d12600> <HMDataTool: 0x8d12600>
4.线程锁和GCD实现单例模式
4.1线程锁和GCD实现单粒模式
- +(Muser *)sharedMuser
- {
- staticstatic *user = nil;
- @synchronized(self)
- {
- if (user == nil) {
- user = [[Muser alloc] init];
- }
- }
- return user;
- }
GCD实现单粒
- +(<span style="font-family: Arial, Helvetica, sans-serif;">sharedsegMentTitles</span><span style="font-family: Arial, Helvetica, sans-serif;"> *</span><span style="font-family: Arial, Helvetica, sans-serif;">)sharedsegMentTitles</span>
- {
- static SwitchMenuViewModel * segTitles = nil;
- static dispatch_once_t once;
- dispatch_once(&once,^{
- if (segTitles == nil) {
- segTitles = [[SwitchMenuViewModel alloc]init];
- }
- });
- return segTitles;
- }
4.2为什么使用宏?
- // .h文件 shared##name 是让前面HMSingletonH(name) 接收到的参数拼接起来
- #define HMSingletonH(name) + (instancetype)shared##name;
- // .m文件 如果是ARC
- #if __has_feature(objc_arc)
- #define HMSingletonM(name) \
- static id _instace; \
- \
- + (id)allocWithZone:(struct _NSZone *)zone \
- { \
- static dispatch_once_t onceToken; \
- dispatch_once(&onceToken, ^{ \
- _instace = [super allocWithZone:zone]; \
- }); \
- return _instace; \
- } \
- \
- + (instancetype)shared##name \
- { \
- static dispatch_once_t onceToken; \
- dispatch_once(&onceToken, ^{ \
- _instace = [[self alloc] init]; \
- }); \
- return _instace; \
- } \
- \
- - (id)copyWithZone:(NSZone *)zone \
- { \
- return _instace; \
- }
- //如果是非ARC
- #else
- #define HMSingletonM(name) \
- static id _instace; \
- \
- + (id)allocWithZone:(struct _NSZone *)zone \
- { \
- static dispatch_once_t onceToken; \
- dispatch_once(&onceToken, ^{ \
- _instace = [super allocWithZone:zone]; \
- }); \
- return _instace; \
- } \
- \
- + (instancetype)shared##name \
- { \
- static dispatch_once_t onceToken; \
- dispatch_once(&onceToken, ^{ \
- _instace = [[self alloc] init]; \
- }); \
- return _instace; \
- } \
- \
- - (id)copyWithZone:(NSZone *)zone \
- { \
- return _instace; \
- } \
- \
- - (oneway void)release { } \
- - (id)retain { return self; } \
- - (NSUInteger)retainCount { return 1;} \
- - (id)autorelease { return self;}
- #endif
- //
- // HMViewController.m
- //
- #import "HMViewController.h"
- #import "HMMusicTool.h"
- #import "HMMovieTool.h"
- #import "HMDataTool.h"
- #import "HMPerson.h"
- @interface HMViewController ()
- @end
- @implementation HMViewController
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- // HMMusicTool *tool1 = [HMMusicTool sharedMusicTool];
- // HMMusicTool *tool2 = [HMMusicTool sharedMusicTool];
- //
- // HMMovieTool *tool3 = [HMMovieTool sharedMovieTool];
- // HMMovieTool *tool4 = [HMMovieTool sharedMovieTool];
- //
- // HMDataTool *tool5 = [HMDataTool sharedDataTool];
- // HMDataTool *tool6 = [HMDataTool sharedDataTool];
- //
- // NSLog(@"%@ %@", tool5, tool6);
- HMPerson *p = [[HMPerson alloc] init];
- #if __has_feature(objc_arc)
- // 编译器是ARC环境
- #else
- // 编译器是MRC环境
- [p release];
- #endif
- }
- @end
单例模式——使用GCD实现单例模式 & 非ARC单例模式 &使用GCD和线程锁实现单例模式-b的更多相关文章
- 单例模式ARC和非ARC
ARC环境下的单例模式: static id _instance = nil; + (id)allocWithZone:(struct _NSZone *)zone { if (_instance = ...
- Objective-C在ARC下结合GCD的单例模式和宏模版
单例模式在iOS开发过程中经常用到,苹果提供过objective c单例的比较官方的写法: static MyGizmoClass *sharedGizmoManager = nil; + (MyGi ...
- iOS学习总结之ARC和非ARC的单例模式实现
iOS单例模式的实现 首先我们要明白下面三个问题: 什么是单例模式 单例模式的优点 如何实现单例模式 1.什么是单例模式 单例模式(Singleton):单例模式确保对于一个给定的类只有一个实例存在, ...
- java——多线程——单例模式的static方法和非static方法是否是线程安全的?
单例模式的static方法和非static方法是否是线程安全的? 答案是:单例模式的static方法和非static方法是否是线程安全的,与单例模式无关.也就说,如果static方法或者非static ...
- java多线程(一)——线程安全的单例模式
概念: java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例.饿汉式单例.登记式单例三种. 单例模式有一下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3. ...
- [No000016F]高并发下线程安全的单例模式(最全最经典)
在所有的设计模式中,单例模式是我们在项目开发中最为常见的设计模式之一,而单例模式有很多种实现方式,你是否都了解呢?高并发下如何保证单例模式的线程安全性呢?如何保证序列化后的单例对象在反序列化后任然是单 ...
- 【多线程那些事儿】如何使用C++写一个线程安全的单例模式?
如何写一个线程安全的单例模式? 单例模式的简单实现 单例模式大概是流传最为广泛的设计模式之一了.一份简单的实现代码大概是下面这个样子的: class singleton { public: stati ...
- Android之线程安全的单例模式,Adapter注意事项之引用传值
线程安全的单例模式单位模式一般写法如下: public static FestivalLab mInstance; private FestivalLab() { } public static Fe ...
- 线程安全的单例模式还需要对成员变量的set get方法设置锁么
不需要,线程安全的单例模式,在获得对象时已经加锁了,保证每时每刻只有一个线程获得此单例对象.所以不需要再上锁了啊
随机推荐
- jquery dragsort table实现拖拽排序
转自:http://haoningabc.iteye.com/blog/1593640 dragsort官网地址:http://dragsort.codeplex.com/ html代码如下(需引入j ...
- DataGridView 列大写、列只能输入数字 分类: DataGridView 2014-12-07 08:40 332人阅读 评论(0) 收藏
列大写: 说明:调用EditingControlShowing事件 private void dgvGoods_EditingControlShowing(object sender, DataGri ...
- PDF模板报表导出(Java+Acrobat+itext)
1. 首先要安装Adobe Acrobat,装好之后用Acrobat从一个word,excel或者pdf中转换一个pdf模板,我做的模板很简单,直接写一个简单的word再生成一个pdf表单,之后编辑文 ...
- Word2007怎样从随意页開始设置页码 word07页码设置毕业论文
Word2007怎样从随意页開始设置页码 word07页码设置毕业论文 页開始设置页码. 一.插入页码 插入→页眉和页脚→页码→页面底端→普通数字3 说明:被→分隔的内容分别为选项卡,模块,命令but ...
- Windows如何打包Qt程序
很多Qt爱好者想发布自己的Qt软件,但却发现在其他没有安装Qt SDK的机器上无法运行,这就是本文想要说明的问题.现在网上大部分软件都要发布自己开发的应用程序,都会打包到exe文件中,待安装完exe文 ...
- [转] CSS float 浮动属性
http://www.cnblogs.com/polk6/p/3142187.html CSS float 浮动属性 本篇主要介绍float属性:定义元素朝哪个方向浮动. 目录: 1. 页面布局方式: ...
- 理解JavaScript的定时器与回调机制
定时器方法 JavaScript是单线程的.虽然HTML5已经开始支持异步js了. JavaScript的setTimeout与setInterval看起来就像已经是多线程的了.但实际上setTime ...
- poj 3463 Sightseeing(次短路+条数统计)
/* 对dij的再一次理解 每个点依旧永久标记 只不过这里多搞一维 0 1 表示最短路还是次短路 然后更新次数相当于原来的两倍 更新的时候搞一下就好了 */ #include<iostream& ...
- MEF依赖注入调试小技巧!
自从哥的项目使用MEF以来,天天那个纠结啊,甭提了.稍有错误,MEF就报错,但就不告诉你哪错了,大爷的. 后来看了MEFX的相关调试方法,感觉也不太理想,根本不够直观的看到错误原因,也许是没有深入学习 ...
- C#语法糖之第一篇:自动属性&隐式类型
今天给大家分享一下C#语法糖的简单的两个知识点吧. 自动属性:在 C# 4.0 和更高版本中,当属性的访问器中不需要其他逻辑时,自动实现的属性可使属性声明更加简洁. 客户端代码还可通过这些属性创建对象 ...