iOS开发实践之多线程(单例模式)
单例模式的作用:可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问,从而方便地控制了实例个数,并节约系统资源。
单例模式的使用场合:在这个应用程序中,共享一份资源(这份资源只需要创建初始化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开发实践之多线程(单例模式)的更多相关文章
- iOS开发网络篇—多线程断点下载
iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始, ...
- iOS 开发实践之 Auto Layout
原:http://xuexuefeng.com/autolayout/?utm_source=tuicool 本文是博主 iOS 开发实践系列中的一篇,主要讲述 iOS 中 Auto Layout(自 ...
- iOS开发——实用技术OC篇&单例模式的实实现(ACR&MRC)
单例模式的实实现(ACR&MRC) 在iOS开发中单例模式是一种非常常见的模式,虽然我们自己实现的比较少,但是,系统却提供了不少的到来模式给我们用,比如最常见的UIApplication,No ...
- iOS开发进阶--1.多线程简介
学习是由已知的知识模型推理未知的知识模型的的过程. 本文适合学习完objective-c基础,想进一步提高做iOS开发的同学阅读. 在说线程的时候,我们先看看进程. 1.进程 每一个运行在系统中的应用 ...
- iOS开发实践-OOM治理
概览 说起iOS的OOM问题大家第一想到的应该更多的是内存泄漏(Memory Leak),因为无论是从早期的MRC还是2011年Apple推出的ARC内存泄漏问题一直是iOS开发者比较重视的问题,比如 ...
- ios开发:GCD多线程
ios有三种多线程编程技术,分别是NSThread,Cocoa NSOperation和GCD,GCD全称Grand Central Dispatch 是Apple开发的一个多核编程的解决方法,在iO ...
- iOS开发进阶-实现多线程的3种方法
相关文章链接: 1.多线程简介 2.实现多线程的3种方法 ......待续 前言 在多线程简介中,我已经说明过了,为了提高界面的流畅度以及用户体验.我们务必要把耗时的操作放到别的线程中去执行,千万不要 ...
- 【IOS开发】《多线程编程指南》笔记
线程是单个应用中可以并发执行多个代码路径的多种技术之一.虽然更新的技术如操作对象(Operation)和Grand Central Dispatch(GCD),提供一个等价现代化和高效的基础设施来实现 ...
- iOS开发笔记2:单例模式(singleton)
每一个app有且仅有一个UIApplication,类似UIApplication“ [UIApplication sharedApplication]”这种一个类有且仅有唯一实例的设计即单例模式. ...
随机推荐
- NSPoint 位置
前言 结构体,这个结构体用来表示事物的一个坐标点. typedef CGPoint NSPoint; struct CGPoint { CGFloat x; CGFloat y; }; typedef ...
- 微信小程序小结(4) -- 分包加载及小程序间跳转
分包加载 某些情况下,开发者需要将小程序划分成不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载(主要是空间不够用,哈哈~). 在构建小程序分包项目时,构建会输出一个或多个功能的分包,其中 ...
- #学习笔记# VALSE 2019.01.09 朱俊彦 --- Learning to Synthesize Images, Videos, and 3D Objects
视频类型:VALSE-webinar 报告时间:2019年01月09日 报告人:MIT朱俊彦 报告题目:Learning to Synthesize Images, Videos, and 3D Ob ...
- js计算每个月的总天数
js中相关日期的计算 var year = new Date().getFullYear(),//计算当前年份 month = new Date().getMonth()+1,//计算当前月份 dat ...
- Nexus 相关
https://help.sonatype.com/repomanager3/download https://www.jianshu.com/p/5fc8fb14d25c
- 提交表单存在html标签报错-检测到有潜在危险的 Request.Form 值
1..aspx页面 在.aspx文件头中加入这句<%@ Page validateRequest="false" %> 2.通用方法 修改web.config文件, & ...
- 6.动态sql - if
满足条件的数据 mapper.xml 满足if条件就执行,不满足就不加 <select id="selectStateByTitle" parameterType=" ...
- appium中driver.wait报IllegalMonitorStateException的解释
在写appium代码的时候,有的人想使用wait方法,写成:driver.wait(),结果抛出异常:IllegalMonitorStateException,看了appium client的api文 ...
- XStream -- a simple library to serialize objects to XML and back again
Link :http://xstream.codehaus.org/index.html http://www.cnblogs.com/hoojo/archive/2011/04/22/2025197 ...
- C++_对象之间的关系与继承
派生类和基类之间的特殊关系是基于C++继承的底层模型的. 实际上,C++有3种继承方式:公有继承.保护继承.私有继承. 公有继承是最常见的关系,它建立一种is-a的关系,即派生类对象也是一种基类,可以 ...