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. winform datagridview如何获取索引 分类: DataGridView 2014-04-11 13:42 216人阅读 评论(0) 收藏

    datagridview.CurrentCell.RowIndex;            是当前活动的单元格的行的索引 datagridview.SelectedRows  ;           ...

  2. Linux查看系统资源占用

    Linux查看系统资源占用 在系统维护的过程中,随时可能有需要查看 CPU和内存的使用率,并根据相应信息分析系统状况的需求.本文介绍一下几种常见的Linux系统资源查看命令. 1.总体内存占用的查看 ...

  3. linux下使用fscanf实现scanf

    首先,我们知道,linux下的scanf标准库函数是一个可变参的函数,那么,我们自己要实现一个scanf也必须是一个可变参的. 其实,在liunx的库中就提供了这样的的宏,来方便我们自己来实现变参函数 ...

  4. 吧php脚本打包成 exe程序

    操作方法 :FQ哦 https://www.youtube.com/watch?v=UQ3zxqh1YXY 有很多方法可以实现 找了个外国的哥们制作的工具 可以吧文件生成很简单的一个独立EXE文件 下 ...

  5. 内部开发环境 git代码托管说明

    前言 随着员工的增加 代码的开发版本管理 提上了日程.初步计划: 1 一台机器 192.168.1.240 git代码版本管理 2 运行环境 192.168.1.241 内部开发运行环境 软件工程师 ...

  6. c++ 文件写样例

    #include <iostream> #include <sstream> #include <fstream>> using namespace std; ...

  7. Java基础知识强化06:使用BigDecimal计算阶乘1+1/2!+1/3!+……

    package himi.hebao04; import java.math.BigDecimal; public class TestDemo07 { public static void main ...

  8. Oracle高版本导出dmp导入Oracle低版本报错:"不是有效的导出文件、头部验证失败"解决方法

    从Oracle高版本中导出dmp,然后导入到Oracle低版本时会报错:"不是有效的导出文件.头部验证失败",解决方法: 方法一:下载软件:AlxcTools,打开后选择要修改的文 ...

  9. WPF中的资源简介、DynamicResource与StaticResource的区别(转)

    什么叫WPF的资源(Resource)?资源是保存在可执行文件中的一种不可执行数据.在WPF的资源中,几乎可以包含图像.字符串等所有的任意CLR对象,只要对象有一个默认的构造函数和独立的属性. 也就是 ...

  10. Deep Learning 学习随记(八)CNN(Convolutional neural network)理解

    前面Andrew Ng的讲义基本看完了.Andrew讲的真是通俗易懂,只是不过瘾啊,讲的太少了.趁着看完那章convolution and pooling, 自己又去翻了翻CNN的相关东西. 当时看讲 ...