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]”这种一个类有且仅有唯一实例的设计即单例模式. ...
随机推荐
- Mybatis环境搭建中的案例分析 及 如果自己编写DAO接口的实现类
Mybatis环境搭建中的案例分析public static void main (String[] args) throws Exception { //读配置文件 //第一个: 使用类加载器,只能 ...
- Div的移动
//JQuery 拖拽本体DIV,把以下代码全部复制即可 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&q ...
- C3算法之我见
C3算法说到底就是merge算法,看了一些帖子,总结说得莫名其妙,大家也是抄来抄去,我试着用自己的话来把这个东西怎么操作的说清楚.当然了我也要抄一些别人的,但是我会 尽量把我认为别人没有讲清楚的那一部 ...
- CSS(十二).transition的应用之CSS中心扩散
实现 css中心向两边扩散的两个核心 1.hover 之前的 垂直居中 2.文字置于最顶层 顺道来讲讲hover 伪元素是不支持 hover 的,不过我们可以给普通的 tag 标签添加 hover 以 ...
- OJ 26217 :Work Scheduling(贪心+优先队列)
约翰有太多的工作要做.为了让农场高效运转,他必须靠他的工作赚钱,每项工作花一个单位时间. 他的工作日从0时刻开始,有10^8个单位时间.在任一时刻,他都可以选择编号1~N的N(1 <= N &l ...
- 江西财经大学第一届程序设计竞赛 H
链接:https://www.nowcoder.com/acm/contest/115/H来源:牛客网 题目描述 晚上,小P喜欢在寝室里一个个静静的学习或者思考,享受自由自在的单身生活. 他总是能从所 ...
- 75th LeetCode Weekly Contest Smallest Rotation with Highest Score
Given an array A, we may rotate it by a non-negative integer K so that the array becomes A[K], A[K+1 ...
- Go语言基础之2--字符串详解
一.字符串原理解析 1. 字符串底层就是一个byte数组,所以可以和[]byte类型互相转换:(字符串可以存文本,也可以存二进制,因为其本来就是一个字节流) 2. 字符串之中的字符是不能修改的,那怎 ...
- Python中的None与 NULL(即空字符)的区别
None是Python的特殊类型,NoneType对象,它只有一个值None. 它不支持任何运算也没有任何内建方法. None和任何其他的数据类型比较永远返回False. None有自己的数据类型No ...
- Vue 中怎么发起请求(一)
1.vue 支持开发者引入 jquery 使用 $.ajax() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1.首先,在 package.json 中添加 j ...