单例模式的作用:可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问,从而方便地控制了实例个数,并节约系统资源。

  单例模式的使用场合:在这个应用程序中,共享一份资源(这份资源只需要创建初始化1次)。
一、单例模式-ARC

  1、在.m中保留一个全局的static的实例(static防止其他类extern引用 修改值)

  static id_instance;

  2、重写allocWithZone:方法,在这里创建唯一的实例(注意线程安全)

  + (id)allocWithZone:(struct _NSZone *)zone {

   if (_instance == nil) { // 防止频繁加锁

   @synchronized(self) {

              if (_instance == nil) { // 防止创建多次

   _instance = [super allocWithZone:zone];

     }

   }

  }

    return _instance;

  }

  3、提供1个类方法让外界访问唯一的实例

+ (instancetype)sharedMusicTool {

if (_instance == nil) { // 防止频繁加锁

@synchronized(self) {

if (_instance == nil) { // 防止创建多次

_instance = [[self alloc] init];

}

}

}

return _instance;

}

4、实现copyWithZone:方法

- (id)copyWithZone:(struct _NSZone *)zone {

return _instance;

}

5、如果要实现饿汉式的单例,就实现load方法。(建议不使用)

//当类加载到OC运行时环境中(内存),就会调用一次(一个类只会加载1次)

+(void)load{
    _instance = [[self alloc] init];
}

音乐单例工具类型字代码:

MusicTool.h

#import<UIKit/UIKit.h>

@interface MusicTool:UIView

//提供1个类方法让外界访问唯一的实例

+(instancetype)shareMusicTool;

@end

MusicTool.m

//单例模式:懒汉式

@implementation MusicTool

static id _instance;//static防止其他类extern引用 修改值

/**

* 如果要实现饿汉式的单例,就实现load方法

*  当类加载到OC运行时环境中(内存),就会调用一次(一个类只会加载1次)

*/

//+(void)load{

//    _instance = [[self alloc] init];

//}

   //当第一次使用这个类的时候才会调用

    //+(void)initialize{

//    NSLog(@"===initialize===");

//}

/** alloc 方法内部调用这个方法*/

 + (id)allocWithZone:(struct _NSZone *)zone {

   if (_instance == nil) { // 防止频繁加锁

   @synchronized(self) {

              if (_instance == nil) { // 防止创建多次

   _instance = [super allocWithZone:zone];

     }

   }

  }

    return _instance;

  }

/**

实例化类

*/

+ (instancetype)sharedMusicTool {

if (_instance == nil) { // 防止频繁加锁

@synchronized(self) {

if (_instance == nil) { // 防止创建多次

_instance = [[self alloc] init];

}

}

}

return _instance;

}

/**

实例化类

*/

+ (instancetype)sharedMusicTool {

if (_instance == nil) { // 防止频繁加锁

@synchronized(self) {

if (_instance == nil) { // 防止创建多次

_instance = [[self alloc] init];

}

}

}

return _instance;

}

  二:单例模式 – 非ARC

非ARC中(MRC),单例模式的实现(比ARC多了几个步骤)

实现内存管理方法

- (id)retain { return self; }

- (NSUInteger)retainCount { return 1; }

- (oneway void)release {}

- (id)autorelease { return self; }

MusicTool.m

@implementation MusicTool

static id _instance;  //static 防止其它类extern引用 修改值

+(id)allocWithZone:(struct _NSZone *)zone{}

+(instancetype)sharedMusicTool{}

-(id)copyWithZone:(NSZone *)zone{}同上

//重写release方法,不释放

  -(oneway void)release{

  }

   //重写retain方法,返回单例类

  -(instancetype)retain{

      return self; //return _instance;

   }

  //计算永远为1

  -(NSUInteger)retainCount{

      return 1;

   }

测试:

MusicTool *mt1 = [[MusicTool alloc] init];

MusicTool *mt2 = [MusicTool sharedMusicTool];

MusicTool *mt3 = [mt2 copy];

[mt2 release];//非arc环境下release

地址完全一样!

三:单例模式在ARC\MRC环境下的写法有所不同,可以用宏判断是否为ARC环境

#if __has_feature(objc_arc)

// ARC

#else

// MRC

#endif

把单例定义成宏,抽出公共类

1、HMSingleton.h

// .h文件

#define HMSingletonH(name) + (instancetype)shared##name;

// .m文件

#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; \

}

#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

2、要想再整个项目中都能使用这个宏,则要在预编译pch文件中import导入这个头文件

#ifdef __OBJC__

#import <UIKit/UIKit.h>

#import <Foundation/Foundation.h>

#import "HMSingleton.h"

#endif

3、使用HMSingleton工具类,实现HMMusicTool单例

HMMusicTool.h

#import <Foundation/Foundation.h>

@interface HMMusicTool : NSObject

//宏定义的方法

HMSingletonH(MusicTool)

@end

HMMusicTool.m

#import "HMMusicTool.h"

@implementation HMMusicTool

//宏定义的方法

HMSingletonM(MusicTool)

@end

4.测试:

HMMusicTool *tool1 = [HMMusicTool sharedMusicTool];

HMMusicTool *tool2 = [HMMusicTool sharedMusicTool];

HMMusicTool *tool3 =[[HMMusicTool alloc]init];

HMMusicTool *tool4 =[tool3 copy];

地址相同!

iOS开发实践之多线程(单例模式)的更多相关文章

  1. iOS开发网络篇—多线程断点下载

    iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始, ...

  2. iOS 开发实践之 Auto Layout

    原:http://xuexuefeng.com/autolayout/?utm_source=tuicool 本文是博主 iOS 开发实践系列中的一篇,主要讲述 iOS 中 Auto Layout(自 ...

  3. iOS开发——实用技术OC篇&单例模式的实实现(ACR&MRC)

    单例模式的实实现(ACR&MRC) 在iOS开发中单例模式是一种非常常见的模式,虽然我们自己实现的比较少,但是,系统却提供了不少的到来模式给我们用,比如最常见的UIApplication,No ...

  4. iOS开发进阶--1.多线程简介

    学习是由已知的知识模型推理未知的知识模型的的过程. 本文适合学习完objective-c基础,想进一步提高做iOS开发的同学阅读. 在说线程的时候,我们先看看进程. 1.进程 每一个运行在系统中的应用 ...

  5. iOS开发实践-OOM治理

    概览 说起iOS的OOM问题大家第一想到的应该更多的是内存泄漏(Memory Leak),因为无论是从早期的MRC还是2011年Apple推出的ARC内存泄漏问题一直是iOS开发者比较重视的问题,比如 ...

  6. ios开发:GCD多线程

    ios有三种多线程编程技术,分别是NSThread,Cocoa NSOperation和GCD,GCD全称Grand Central Dispatch 是Apple开发的一个多核编程的解决方法,在iO ...

  7. iOS开发进阶-实现多线程的3种方法

    相关文章链接: 1.多线程简介 2.实现多线程的3种方法 ......待续 前言 在多线程简介中,我已经说明过了,为了提高界面的流畅度以及用户体验.我们务必要把耗时的操作放到别的线程中去执行,千万不要 ...

  8. 【IOS开发】《多线程编程指南》笔记

    线程是单个应用中可以并发执行多个代码路径的多种技术之一.虽然更新的技术如操作对象(Operation)和Grand Central Dispatch(GCD),提供一个等价现代化和高效的基础设施来实现 ...

  9. iOS开发笔记2:单例模式(singleton)

    每一个app有且仅有一个UIApplication,类似UIApplication“ [UIApplication sharedApplication]”这种一个类有且仅有唯一实例的设计即单例模式. ...

随机推荐

  1. day03-Linux操作系统目录结构

    一. Linux系统目录表示        ‘/’表示根目录:                                                            ‘.’表示当前目录 ...

  2. SSH—网上商城之商品图片文件上传

    前言 网上商城中的淘宝图片要显示在页面的前提是图片应该已经在数据库里面,那么怎么实现图片的上传功能呢,这就是今天要说的主题. 内容 需求: 商城后台需要添加图片文件,用来图片显示 解决方式: Stru ...

  3. ThinkPHP3.2.3完整版创建前后台入口文件 http://jingyan.baidu.com/article/7e4409533fc1092fc1e2ef53.html

    ThinkPHP3.2.3完整版创建前后台入口文件   1 2 3 4 5 6 7 分步阅读 ThinkPHP是为了简化企业级应用开发和敏捷WEB应用开发而诞生的优秀的国产php框架,值得我们去探索学 ...

  4. CF1101B Accordion 模拟

    前后扫一遍: #include<iostream> #include<cstdio> #include<algorithm> #include<cstdlib ...

  5. 在服务器上使用 gradle 打包 android 源码

    安装 android-tools mkdir ~/android && cd ~/android   wget https://dl.google.com/android/reposi ...

  6. appium中driver.wait报IllegalMonitorStateException的解释

    在写appium代码的时候,有的人想使用wait方法,写成:driver.wait(),结果抛出异常:IllegalMonitorStateException,看了appium client的api文 ...

  7. 【笔记】Django基础(一)

    ---恢复内容开始--- [笔记]Django基础(一) oldboy Django  一 关于Python框架的本质 1. HTTP协议消息的格式: 请求(request) 请求方法 路径 HTTP ...

  8. codeforces-984D——XOR-pyramid(DP)

    题目传送门 题目描述:给你一个f函数,这个函数的自变量是一个数列,函数表达式就是题目所给的描述,然后给你一个数列,问你数列中某区间  怎么选取 可以使函数值最大. 题目思路:  有关区间选取的问题,很 ...

  9. Educational Codeforces Round 7 B

    Description You are given the current time in 24-hour format hh:mm. Find and print the time after a  ...

  10. dropzone手动上传

    html: <div class="field"> <div id="file" class="dropzone"> ...