1.单利模式概述

链接:  iOS开发懒汉模式&恶寒模式

2.使用GCD实现单利模式

2.1新建一个project,然后新建一个HMDataTool类展示GCD实现单例模式

  1. #import <Foundation/Foundation.h>
  2. @interface HMDataTool : NSObject
  3. + (instancetype)sharedDataTool;
  4. @end
  1. #import "HMDataTool.h"
  2. @implementation HMDataTool
  3. // 用来保存唯一的单例对象
  4. static id _instace;
  5. + (id)allocWithZone:(struct _NSZone *)zone
  6. {
  7. static dispatch_once_t onceToken;
  8. dispatch_once(&onceToken, ^{   //onceToken是GCD用来记录是否执行过 ,如果已经执行过就不再执行(保证执行一次)
  9. _instace = [super allocWithZone:zone];
  10. });
  11. return _instace;
  12. }
  13. + (instancetype)sharedDataTool
  14. {
  15. static dispatch_once_t onceToken;
  16. dispatch_once(&onceToken, ^{
  17. _instace = [[self alloc] init];
  18. });
  19. return _instace;
  20. }
  21. - (id)copyWithZone:(NSZone *)zone
  22. {
  23. return _instace;
  24. }
  25. @end
  1. #import "htingViewController.h"
  2. #import"HMDataTool.h"
  3. @interface htingViewController ()
  4. @end
  5. @implementation htingViewController
  6. - (void)viewDidLoad
  7. {
  8. [super viewDidLoad];
  9. // Do any additional setup after loading the view, typically from a nib.
  10. HMDataTool *tool1 = [HMDataTool sharedDataTool];
  11. HMDataTool *tool2 = [HMDataTool sharedDataTool];
  12. HMDataTool *tool3 = [[HMDataTool alloc] init];
  13. HMDataTool *tool4 = [[HMDataTool alloc] init];
  14. NSLog(@"%@ %@ %@ %@", tool1, tool2, tool3, tool4);
  15. }
  16. @end

打印结果

  1. 使用GCD实现单利模式[2334:607] <HMDataTool: 0x8f064c0> <HMDataTool: 0x8f064c0> <HMDataTool: 0x8f064c0> <HMDataTool: 0x8f064c0>

3.非ARC实现单例模式

3.1非ARC内存管理模式下对象必须手动释放,为了防止那个唯一的单例对象被释放掉,则只需要重写下面的几个方法即可

  1. - (oneway void)release { }
  2. - (id)retain { return self; }
  3. - (NSUInteger)retainCount { return 1;}
  4. - (id)autorelease { return self;}

3.2通过新建一个HMDataTool类来演示非ARC单例模式

 
  1. //  HMDataTool.h
  2. #import <Foundation/Foundation.h>
  3. @interface HMDataTool : NSObject
  4. + (instancetype)sharedDataTool;
  5. @end
  1. //
  2. //  HMDataTool.m
  3. //  03-单例模式-Singleton(掌握)
  4. //
  5. //  Created by apple on 14-9-16.
  6. //  Copyright (c) 2014年 heima. All rights reserved.
  7. //
  8. #import "HMDataTool.h"
  9. @implementation HMDataTool
  10. // 用来保存唯一的单例对象
  11. static id _instace;
  12. + (id)allocWithZone:(struct _NSZone *)zone
  13. {
  14. static dispatch_once_t onceToken;
  15. dispatch_once(&onceToken, ^{
  16. _instace = [super allocWithZone:zone];
  17. });
  18. return _instace;
  19. }
  20. + (instancetype)sharedDataTool
  21. {
  22. static dispatch_once_t onceToken;
  23. dispatch_once(&onceToken, ^{
  24. _instace = [[self alloc] init];
  25. });
  26. return _instace;
  27. }
  28. - (id)copyWithZone:(NSZone *)zone
  29. {
  30. return _instace;
  31. }
  32. /**
  33. *  重写下面几个关于引用计数器的方法就可以防止修改引用计数器的值,
  34. 这样就可以这个对象永远停留在内存中(因为这几个方法都是空的,所以尽管怎么调用,都没有作用)
  35. *
  36. *  @return <#return value description#>
  37. */
  38. - (oneway void)release { }
  39. - (id)retain { return self; }
  40. - (NSUInteger)retainCount { return 1;}
  41. - (id)autorelease { return self;}
  42. @end
  1. //
  2. //  HMViewController.h
  3. #import <UIKit/UIKit.h>
  4. @interface HMViewController : UIViewController
  5. @end
  1. //
  2. //  HMViewController.m
  3. #import "HMViewController.h"
  4. #import "HMDataTool.h"
  5. @interface HMViewController ()
  6. @end
  7. @implementation HMViewController
  8. - (void)viewDidLoad
  9. {
  10. [super viewDidLoad];
  11. HMDataTool *tool1 = [[HMDataTool alloc] init];
  12. HMDataTool *tool2 = [[HMDataTool alloc] init];
  13. HMDataTool *tool3 = [HMDataTool sharedDataTool];
  14. HMDataTool *tool4 = [HMDataTool sharedDataTool];
  15. /**
  16. *  重写了下面几个方法之后,则随便释放N次都没有用了
  17. - (oneway void)release { }
  18. - (id)retain { return self; }
  19. - (NSUInteger)retainCount { return 1;}
  20. - (id)autorelease { return self;}
  21. */
  22. [tool4 autorelease];
  23. [tool4 autorelease];
  24. [tool4 autorelease];
  25. [tool4 autorelease];
  26. [tool4 autorelease];
  27. NSLog(@"%@ %@ %@ %@", tool1, tool2, tool3, tool4);
  28. }<pre name="code" class="objc">+(loginModel *)sharedloginModel
  29. {
  30. static loginModel *loginmodle = nil;
  31. @synchronized(self)
  32. {
  33. if (loginmodle == nil) {
  34. loginmodle = [[loginModel alloc] init];
  35. }
  36. }
  37. return loginmodle;
  38. }

@end


运行结果

单例模式-ARC(掌握)[2592:607] <HMDataTool: 0x8d12600> <HMDataTool: 0x8d12600> <HMDataTool: 0x8d12600> <HMDataTool: 0x8d12600>

 

4.线程锁和GCD实现单例模式

4.1线程锁和GCD实现单粒模式

线程锁实现单粒
  1. +(Muser *)sharedMuser
  2. {
  3. staticstatic *user = nil;
  4. @synchronized(self)
  5. {
  6. if (user == nil) {
  7. user = [[Muser alloc] init];
  8. }
  9. }
  10. return user;
  11. }

GCD实现单粒

  1. +(<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>
  2. {
  3. static SwitchMenuViewModel * segTitles = nil;
  4. static dispatch_once_t once;
  5. dispatch_once(&once,^{
  6. if (segTitles == nil) {
  7. segTitles = [[SwitchMenuViewModel alloc]init];
  8. }
  9. });
  10. return segTitles;
  11. }

4.2为什么使用宏?

 
假设一个项目中有多个类需要单例,则需要每个类都实现一遍单例,这样很繁琐,因此可以采用定义宏的方式,写一个单例文件添加到项目中然后在项目的Prefix.pch文件中得这个地方包含进去即可
  1. // .h文件 shared##name 是让前面HMSingletonH(name) 接收到的参数拼接起来
  2. #define HMSingletonH(name) + (instancetype)shared##name;
  3. // .m文件  如果是ARC
  4. #if __has_feature(objc_arc)
  5. #define HMSingletonM(name) \
  6. static id _instace; \
  7. \
  8. + (id)allocWithZone:(struct _NSZone *)zone \
  9. { \
  10. static dispatch_once_t onceToken; \
  11. dispatch_once(&onceToken, ^{ \
  12. _instace = [super allocWithZone:zone]; \
  13. }); \
  14. return _instace; \
  15. } \
  16. \
  17. + (instancetype)shared##name \
  18. { \
  19. static dispatch_once_t onceToken; \
  20. dispatch_once(&onceToken, ^{ \
  21. _instace = [[self alloc] init]; \
  22. }); \
  23. return _instace; \
  24. } \
  25. \
  26. - (id)copyWithZone:(NSZone *)zone \
  27. { \
  28. return _instace; \
  29. }
  30. //如果是非ARC
  31. #else
  32. #define HMSingletonM(name) \
  33. static id _instace; \
  34. \
  35. + (id)allocWithZone:(struct _NSZone *)zone \
  36. { \
  37. static dispatch_once_t onceToken; \
  38. dispatch_once(&onceToken, ^{ \
  39. _instace = [super allocWithZone:zone]; \
  40. }); \
  41. return _instace; \
  42. } \
  43. \
  44. + (instancetype)shared##name \
  45. { \
  46. static dispatch_once_t onceToken; \
  47. dispatch_once(&onceToken, ^{ \
  48. _instace = [[self alloc] init]; \
  49. }); \
  50. return _instace; \
  51. } \
  52. \
  53. - (id)copyWithZone:(NSZone *)zone \
  54. { \
  55. return _instace; \
  56. } \
  57. \
  58. - (oneway void)release { } \
  59. - (id)retain { return self; } \
  60. - (NSUInteger)retainCount { return 1;} \
  61. - (id)autorelease { return self;}
  62. #endif
  1. //
  2. //  HMViewController.m
  3. //
  4. #import "HMViewController.h"
  5. #import "HMMusicTool.h"
  6. #import "HMMovieTool.h"
  7. #import "HMDataTool.h"
  8. #import "HMPerson.h"
  9. @interface HMViewController ()
  10. @end
  11. @implementation HMViewController
  12. - (void)viewDidLoad
  13. {
  14. [super viewDidLoad];
  15. //    HMMusicTool *tool1 = [HMMusicTool sharedMusicTool];
  16. //    HMMusicTool *tool2 = [HMMusicTool sharedMusicTool];
  17. //
  18. //    HMMovieTool *tool3 = [HMMovieTool sharedMovieTool];
  19. //    HMMovieTool *tool4 = [HMMovieTool sharedMovieTool];
  20. //
  21. //    HMDataTool *tool5 = [HMDataTool sharedDataTool];
  22. //    HMDataTool *tool6 = [HMDataTool sharedDataTool];
  23. //
  24. //    NSLog(@"%@ %@", tool5, tool6);
  25. HMPerson *p = [[HMPerson alloc] init];
  26. #if __has_feature(objc_arc)
  27. // 编译器是ARC环境
  28. #else
  29. // 编译器是MRC环境
  30. [p release];
  31. #endif
  32. }
  33. @end

 
为什么使用宏?
这样可以方便项目中的其它单例的创建,只需要在项目中包含即可共用,而不必要再次用代码为每一个单例对象实现单例

单例模式——使用GCD实现单例模式 & 非ARC单例模式 &使用GCD和线程锁实现单例模式-b的更多相关文章

  1. 单例模式ARC和非ARC

    ARC环境下的单例模式: static id _instance = nil; + (id)allocWithZone:(struct _NSZone *)zone { if (_instance = ...

  2. Objective-C在ARC下结合GCD的单例模式和宏模版

    单例模式在iOS开发过程中经常用到,苹果提供过objective c单例的比较官方的写法: static MyGizmoClass *sharedGizmoManager = nil; + (MyGi ...

  3. iOS学习总结之ARC和非ARC的单例模式实现

    iOS单例模式的实现 首先我们要明白下面三个问题: 什么是单例模式 单例模式的优点 如何实现单例模式 1.什么是单例模式 单例模式(Singleton):单例模式确保对于一个给定的类只有一个实例存在, ...

  4. java——多线程——单例模式的static方法和非static方法是否是线程安全的?

    单例模式的static方法和非static方法是否是线程安全的? 答案是:单例模式的static方法和非static方法是否是线程安全的,与单例模式无关.也就说,如果static方法或者非static ...

  5. java多线程(一)——线程安全的单例模式

    概念: java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例.饿汉式单例.登记式单例三种. 单例模式有一下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建自己的唯一实例. 3. ...

  6. [No000016F]高并发下线程安全的单例模式(最全最经典)

    在所有的设计模式中,单例模式是我们在项目开发中最为常见的设计模式之一,而单例模式有很多种实现方式,你是否都了解呢?高并发下如何保证单例模式的线程安全性呢?如何保证序列化后的单例对象在反序列化后任然是单 ...

  7. 【多线程那些事儿】如何使用C++写一个线程安全的单例模式?

    如何写一个线程安全的单例模式? 单例模式的简单实现 单例模式大概是流传最为广泛的设计模式之一了.一份简单的实现代码大概是下面这个样子的: class singleton { public: stati ...

  8. Android之线程安全的单例模式,Adapter注意事项之引用传值

    线程安全的单例模式单位模式一般写法如下: public static FestivalLab mInstance; private FestivalLab() { } public static Fe ...

  9. 线程安全的单例模式还需要对成员变量的set get方法设置锁么

    不需要,线程安全的单例模式,在获得对象时已经加锁了,保证每时每刻只有一个线程获得此单例对象.所以不需要再上锁了啊

随机推荐

  1. 10881 - Piotr's Ants(排序)

    题目链接:10881 - Piotr's Ants 题目大意:在一个长为L的木棒上有n只蚂蚁,给出蚂蚁的初始位置以及方向,问说移动T秒后各个蚂蚁的位置以及状态,如果两只蚂蚁在移动的过程中相撞,则会同时 ...

  2. DOS命令创建以日期为文件名的任务计划TXT文件

    因为每天早上都要做计划,所以做了个批处理文件来创建任务计划TXT文件 文件内容展示如下: 2013/07/09 周二 今日任务: 1. 2. 待办任务: 1. 2. 出现问题: 解决办法: 出现问题: ...

  3. POJ 1737 统计有n个顶点的连通图有多少个 (带标号)

    设f(n)为所求答案 g(n)为n个顶点的非联通图 则f(n) + g(n) = h(n) = 2^(n * (n - 1) / 2) 其中h(n)是n个顶点的联图的个数 这样计算 先考虑1所在的连通 ...

  4. 详细分享UICollectionView的自定义布局(瀑布流, 线性, 圆形…)

    前言: 本篇文章不是分享collectionView的详细使用教程, 而是属于比较’高级’的collectionView使用技巧, 阅读之前, 我想你已经很熟悉collectionView的基本使用, ...

  5. Eclipse打开当前所属文件所在windows中的文件夹

    1.Eclipse设置 依次展开如下菜单:    Run ---- External Tools ---- External Tools Configurations    在 program 下面新 ...

  6. json 序列化的两种方式

    JavaScriptSerializer Serializer = new JavaScriptSerializer(); ResultData<EUserData> resultMode ...

  7. asp.net 的状态管理

    状态管理 (state management) 在Web应用程序中,一向是很重要的课题,良好的状态管理可以帮助开发人员发展出具有状态持续能力的应用程序(像是工作流程型应用程序或是电子商务应用程序),但 ...

  8. c#读取文件

    你平时是怎么读取文件的?使用流读取.是的没错,C#给我们提供了非常强大的类库(又一次吹捧了.NET一番), 里面封装了几乎所有我们可以想到的和我们没有想到的类,流是读取文件的一般手段,那么你真的会用它 ...

  9. svn的初级使用

    首先呢 你需要下载一个软件  比如说是 Cornerstone. 进行安装好之后 然后 然后输入账号密码 就可以了 然后去xcode去进行相关的配置 点击第二个进入 偏好设置 点击最下边的+ 点击第二 ...

  10. idea 配置node Run

    1.node 2.nodemon 支持热部署 3.supervisor  支持执部署