单例模式——使用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 进度条集锦
http://sc.chinaz.com/tag_jiaoben/JinDuTiao.html?qq-pf-to=pcqq.group
- 使用BSD socket编写Windows版的网络程序
我们知道BSD Socket是标准的套接字规范,那么怎么在windows使用他们呢? 我们首先要引用<winsock2.h>和ws2_32.lib 然后,执行WSAStartup #ifd ...
- c#委托和事件(上)
C# 中的委托和事件 引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真 ...
- JS代码获取当前日期时支持IE,不兼容FF和chrome,解决这个问题,我们需要把获取时间的getYear()函数换成getFullYear()
以前在页面中获得当前时间的方法如下: function SelectTodayClient() { var d = new Date(); var taday = d.getYear() + &quo ...
- SEO中最常见的几个错误
昨天答应给放点干活的,今天如约而来! SEO中最常见的几个错误: 1.关键词 人们往往想当然的选择自己喜欢的keyword,但用户在搜索时,根本不会使用它们.比方说,你选择"优化果酱&q ...
- 标记偏置 隐马尔科夫 最大熵马尔科夫 HMM MEMM
隐马尔科夫模型(HMM): 图1. 隐马尔科夫模型 隐马尔科夫模型的缺点: 1.HMM仅仅依赖于每个状态和它相应的观察对象: 序列标注问题不仅和单个词相关,并且和观察序列的长度,单词的上下文,等等相关 ...
- Fix java version mismatch in windows---stackoverflow
Question: I have the 64bit version of the jdk installed on windows 7. I installed the 32 bit version ...
- 提取DLL类库代码
@SET destFolder=.\bin@XCOPY /I /Y %SYSTEMDRIVE%\WINDOWS\assembly\GAC_MSIL\Microsoft.ReportViewer.Pro ...
- FaceBook要在视频领域打败YouTube?
据<纽约时报>报道,FaceBook正在探索一项新的策略来直接把音乐视频嵌入到用户的News Feeds中.目前,具有代表性的视频网站有YouTube和Vimeo,它们可以在社交网络上分享 ...
- Linux sed命令常用方法
sed也成stream editor,流编辑器,是Linux上常用的文本处理工具. 通用格式:sed 行范围 模式/RegExp/ 文件 模式: d 删除 p 打印符合条件的行 a \strin ...