单例模式——使用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方法设置锁么
不需要,线程安全的单例模式,在获得对象时已经加锁了,保证每时每刻只有一个线程获得此单例对象.所以不需要再上锁了啊
随机推荐
- 在Tomcat下部署web项目
每个web项目可以以两种方式存在,如联合风控项目,Urc.war,另一中是Urc解压后的目录结构.而tomcat目录下的\webapps\下则均是要部署的web项目解压后的文件夹,启动tomcat后, ...
- 提高你的Java代码质量吧:正确使用String、StringBuffer、StringBuilder
一.建议 CharSequence接口有三个实现类与字符串相关:String.StringBuffer.StringBuilder,虽然它们都与字符串相关,但是其处理机制不同. 根据不同的场景,建议 ...
- IE8下提示'console'没有定义错误
在开发的过程中因为调试的原因,在代码中增加console.info("xxxx"),而未进行删除 在IE8下測试该代码所在的页面报错,例如以下: 须要注意的是,使用console对 ...
- android 49 广播接收者中启动其他组件
main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" andro ...
- systrace跟踪 Android性能优化
http://blog.csdn.net/oujunli/article/details/8138172 http://blog.csdn.net/oujunli/article/details/50 ...
- MapReduce实战:统计不同工作年限的薪资水平
1.薪资数据集 我们要写一个薪资统计程序,统计数据来自于互联网招聘hadoop岗位的招聘网站,这些数据是按照记录方式存储的,因此非常适合使用 MapReduce 程序来统计. 2.数据格式 我们使用的 ...
- iOS开发之支付宝集成
项目中要用到支付功能,需要支付宝,微信,银联三大支付,所以打算总结一下,写两篇文章,方便以后的查阅, 大家在做的时候也能稍微参考下,用到的地方避免再次被坑.这是第二篇支付宝集成,第一篇银联支付在这里. ...
- Ant学习笔记(2) 在Eclipse中使用Ant
Eclipse默认提供了对Ant的支持,在Eclipse中不需要安装任何插件就能直接编辑和运行Ant.Eclipse中包含了一个Ant脚本编辑器,Ant脚本编辑器提供了对Ant脚本的语法搞来高亮.自动 ...
- Python开发【第二十二篇】:Web框架之Django【进阶】
Python开发[第二十二篇]:Web框架之Django[进阶] 猛击这里:http://www.cnblogs.com/wupeiqi/articles/5246483.html 博客园 首页 ...
- $(this).next()与$(this).children()
$(this).next() 当前元素同级的下个元素,而非子元素 $(this).children() 是当前元素的下一级元素的集合,就是子元素的集合,而不管子元素的后代元素 所以这两个没有什么可比性 ...