单例模式——使用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方法设置锁么
不需要,线程安全的单例模式,在获得对象时已经加锁了,保证每时每刻只有一个线程获得此单例对象.所以不需要再上锁了啊
随机推荐
- kafka consumer频繁reblance
转载请注明地址http://www.cnblogs.com/dongxiao-yang/p/5417956.html 结论与下文相同,kafka不同topic的consumer如果用的groupid名 ...
- win7重装系统时,使用PE工具箱进入系统看到的“C盘变成0.2G,D盘变成48G左右”这是什么回事?
引入: 今天帮同学重装系统,重装系统使用的方法是利用PE工具箱制作出启动U盘,进行重装系统. 我的步骤是 第一步:开机按F2挂载U盘优先启动,于是开机时就进入PE微系统 第二步: 用分区工具(Disk ...
- Struts 有哪些经常使用标签库
Struts 有哪些经常使用标签库 1.html标签库 2.bean标签库 3.logic标签库
- Android 举例说明自己的定义Camera图片和预览,以及前后摄像头切换
如何调用本地图片,并调用系统拍摄的图像上一博文解释(http://blog.csdn.net/a123demi/article/details/40003695)的功能. 而本博文将通过实例实现自己定 ...
- iOS--NSAttributedString使用介绍
iOS–NSAttributedString使用介绍 原文见: http://www.itnose.net/detail/6177538.html http://***/html/topnews201 ...
- VBA开发中的前绑定与后绑定
凡是能用createobject创建的对象,都可以在引用相对应的运行库(library)文件之后在对象浏览器中得到它的方法.属性.枚举和事件列表,比如Shell.Application对象在Shell ...
- java 反射调用支付SDK
在android开发中会遇到各种SDK的接入,很是麻烦.最初在想能不能把所有的SDK都 融合到一个当中,发现有点异想天开.但是也可以解决SDK资源不小心没有引入,导致程序调用接口崩溃问题.经过查资料, ...
- Android使用 selector 自定义控件背景 (以spinner 为例)
1. 在drawable中设置背景spinner_style.xml 文件 如图: 2. 在 styles.xml 中添加该背景 3. 最后在 spinner 控件添加样式 4.参考 http:// ...
- CI 笔记2,(命令规范等)
调试模式开启,$this->output->enable_profiler(TRUE); 保留字,不能和控制器重名,有3个,CI_Controller ,Default, index.这三 ...
- 制作SSL证书
上一节介绍了OpenSSL的目录结构,本节介绍一下SSL证书的制作. OpenSSL安装后建议把其中的bin目录添加到系统环境变量中,方便以后操作. 建立一个新的目录SSL专门用来制作证书. 建立证书 ...