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

  单例模式的使用场合:在这个应用程序中,共享一份资源(这份资源只需要创建初始化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. 使用Google浏览器开发者工具学习HTTP请求记录

    GET请求 1.Google浏览器开发者工具截图图示 2.General Request URL :为请求链接 Status Code :为HTTP响应状态码 3.ResponseHeaders :响 ...

  2. 为什么选择Angular 2?

    没有选择是痛苦的,有太多的选择却更加痛苦.而后者正是目前前端领域的真实写照.新的框架层出不穷:它难吗?它写得快吗?可维护性怎样?运行性能如何?社区如何?前景怎样?好就业吗?好招人吗?组建团队容易吗? ...

  3. C++基础学习10:继承

    继承是类与类之间的关系,是一个很简单很直观的概念,与现实世界中的继承(例如儿子继承父亲财产)类似. 继承可以理解为一个类从另一个类获取方法(函数)和属性(成员变量)的过程.如果类B继承于类A,那么B就 ...

  4. apache 日志分割

    Window apache 全局设置日志分割   apache  [ httpd.conf ] 配置文件 开启日志模块:LoadModule log_config_module modules/mod ...

  5. CodeForces - 359C-Prime Number

    Simon has a prime number x and an array of non-negative integers a1, a2, ..., an. Simon loves fracti ...

  6. poj3713 Transferring Sylla 枚举+tarjan判割点

    其实就是判断是否为三连通图 三连通图指的是去掉3个点就不连通的图,但是并没有直接求三连通的算法.著名的Tarjan算法可以求解连通和割点,再枚举删除一个点就能达到三连通的目的. 先看用例2,是由用例1 ...

  7. datatables通过ajax调用渲染数据,怎么根据数据给td添加class

    html: <table id="table8" cellpadding="0" cellspacing="0" border=&qu ...

  8. hdu2553 N皇后问题(dfs+回溯)

    N皇后问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  9. InterruptionInJava

    package com.test; public class InterruptionInJava implements Runnable{ public static void main(Strin ...

  10. Autel MaxiSys Pro MS908P

    Autel MaxiSys pro MS908P is an evolutionary smart solution for specialized automotive diagnosis and ...