单例模式——使用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方法设置锁么
不需要,线程安全的单例模式,在获得对象时已经加锁了,保证每时每刻只有一个线程获得此单例对象.所以不需要再上锁了啊
随机推荐
- c#基础语言编程-文件流操作
引言 在System.IO 命名空间下提供了一系列的类,我们可以通过相应的类进行文件.目录.数据流的操作. 1.File类:提供用于创建.复制.删除.移动和打开文件的静态方法.File类 2.File ...
- Unity3d UnityEditor EditorWindow 自定义窗体控件
功能:是因为公司的模型组需要一个插件,在MAYA中有很多个复制物体,导出的时候只导出一个,其他相同的物体只导出点的位置信息.这样进入Unity里就是一个物体和N个相同物体的位置点,代码简单但是需要用插 ...
- 工厂模式 - 程序实现(java)
09年5月CSDN一网友提出如下问题: 设计一个用于管理银行客户的类BankCustomer: 仅描述客户的几个重要方面: 帐号.身份证号.姓名.联系方式.密码.账户余额. 所有的成员变量均用priv ...
- PDF模板报表导出(Java+Acrobat+itext)
1. 首先要安装Adobe Acrobat,装好之后用Acrobat从一个word,excel或者pdf中转换一个pdf模板,我做的模板很简单,直接写一个简单的word再生成一个pdf表单,之后编辑文 ...
- C#系列之值类型和引用类型
前言 这几天一直在思考这章讨论什么, 在上一章讨论string的时候牵涉到引用类型,那么我们这一章讨论讨论一下,值类型和引用类型. 值类型和引用类型,它们的区别来源于传值方式.有人会认为值类型就存在栈 ...
- [React] React Fundamentals: with-addons - ReactLink
It can be tedious to type out all the boilerplate needed to get the DOM and states in React to synch ...
- hibernate批量删除和更新数据
转载自:http://blog.csdn.net/yuhua3272004/article/details/2909538 Hibernate3.0 採用新的基于ANTLR的HQL/SQL查询翻译器, ...
- Qt 学习之路:线程和 QObject
前面两个章节我们从事件循环和线程类库两个角度阐述有关线程的问题.本章我们将深入线程间得交互,探讨线程和QObject之间的关系.在某种程度上,这才是多线程编程真正需要注意的问题. 现在我们已经讨论过事 ...
- 为什么objc_msgSend必须用汇编实现
译者前言 总是看到有人说用汇编实现objc_msgSend是为了速度快,当然这个不可否认.但是难道没有别的原因?于是就看到了这篇文章,遂翻译之!=.= 我自己的理解就是,用汇编实现,是为了应对不同的“ ...
- 重载,重写和super
1.重载的概念:----->在同一个类中,允许存在同名函数,但它们的参数个数或者参数类型不同即可.public static void main(String[] args){System.ou ...