首页 > 代码库 > iOS开发多线程篇—单例模式(ARC)
iOS开发多线程篇—单例模式(ARC)
iOS开发多线程篇—单例模式(ARC)
一、简单说明:
设计模式:多年软件开发,总结出来的一套经验、方法和工具
java中有23种设计模式,在ios中最常用的是单例模式和代理模式。
二、单例模式说明
(1)单例模式的作用 :可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问,从而方便地控制了实例个数,并节约系统资源。
(2)单例模式的使用场合:在整个应用程序中,共享一份资源(这份资源只需要创建初始化1次),应该让这个类创建出来的对象永远只有一个。
(3)单例模式在ARC\MRC环境下的写法有所不同,需要编写2套不同的代码
可以用宏判断是否为ARC环境
#if __has_feature(objc_arc) // ARC#else// MRC#endif
(4)在ARC中,单例模式的实现思路
在.m中保留一个全局的static的实例 static id _instance;
1)重写allocWithZone:方法,在这里创建唯一的实例(注意线程安全)
1 + (id)allocWithZone:(struct _NSZone *)zone2 { @synchronized(self) {3 if (!_instance) {4 _instance = [super allocWithZone:zone];5 }6 }7 return _instance;8 }
2)提供1个类方法让外界访问唯一的实例
1 + (instancetype)sharedSoundTool2 {3 @synchronized(self) {4 if (!_instance) {5 _instance = [[self alloc] init];6 }7 }8 return _instance;9 }
3)实现copyWithZone:方法
1 + (id)copyWithZone:(struct _NSZone *)zone2 {3 return _instance;4 }
(5)非ARC中(MRC),单例模式的实现(比ARC多了几个步骤)
实现内存管理方法
- (id)retain { return self; }
- (NSUInteger)retainCount { return 1; }
- (oneway void)release {}
- (id)autorelease { return self; }
三、单例模式(ARC)
1.说明
重写allocWithzone:方法,控制内存分配。因为alloc内部会调用该方法,每次调用allocWithzone:方法,系统都会创建一块新的内存空间。
alloc方法中:永远只分配一次内存
init方法中:保证所有的MP3数据都只加载一次。
2.代码示例
创建一个音频工具类,继承子NSObject类。
在该类中实现以下代码,观察:
1 // 2 // YYAudioTool.m 3 // 06-单例模式1 4 // 5 // Created by apple on 14-6-25. 6 // Copyright (c) 2014年 itcase. All rights reserved. 7 // 8 9 #import "YYAudioTool.h"10 @interface YYAudioTool ()11 //用来保存mp3文件12 @property(nonatomic,strong)NSMutableDictionary *muscis;13 @end14 @implementation YYAudioTool15 //构造方法16 -(id)init17 {18 if (self=[super init]) {19 //加载所需的音乐资源20 //....21 // self.muscis=[NSMutableDictionary dictionary];22 // self.muscis[@"1.mp3"]=1mp3数据;23 // self.muscis[@"2.mp3"]=2mp3数据;24 }25 return self;26 }27 28 //两个方法的调用29 +(id)alloc30 {31 NSLog(@"alloc----");32 return [super alloc];33 }34 35 //控制内存分配,每次调用allocWithzone:方法,系统都会创建一块新的内存空间36 +(id)allocWithZone:(struct _NSZone *)zone37 {38 NSLog(@"allocWithZone---");39 return [super allocWithZone:zone];40 }41 42 43 44 @end
在主控制器中,创建工具类对象:
1 // 2 // YYViewController.m 3 // 06-单例模式1 4 // 5 // Created by apple on 14-6-25. 6 // Copyright (c) 2014年 itcase. All rights reserved. 7 // 8 9 #import "YYViewController.h"10 #import "YYAudioTool.h"11 12 @interface YYViewController ()13 14 @end15 16 @implementation YYViewController17 18 - (void)viewDidLoad19 {20 [super viewDidLoad];21 YYAudioTool *tool1=[[YYAudioTool alloc]init];22 YYAudioTool *tool2=[[YYAudioTool alloc]init];23 YYAudioTool *tool3=[[YYAudioTool alloc]init];24 YYAudioTool *tool4=[[YYAudioTool alloc]init];25 NSLog(@"%p--%p--%p--%p",tool1,tool2,tool3,tool4);26 }27 28 @end
打印结果:
说明:在alloc内部会调用更底层的方法allocWithZone方法分配内存空间,上面的代码创建了四个不同的对象。
3.单例模式:设计思路
(1)永远只分配一块内存来创建对象
(2)提供一个类方法,返回内部唯一的一个变量
(3)最好保证init方法也只初始化一次
代码示例:
创建一个音频工具类,继承子NSObject类。
在该类中按照设计思路实现以下代码:
YYAudioTool.m文件
1 // 2 // YYAudioTool.m 3 // 06-单例模式1 4 // 5 // Created by apple on 14-6-25. 6 // Copyright (c) 2014年 itcase. All rights reserved. 7 // 8 9 #import "YYAudioTool.h"10 @interface YYAudioTool ()11 //用来保存mp3文件12 @property(nonatomic,strong)NSMutableDictionary *muscis;13 @end14 15 @implementation YYAudioTool16 //定义一份变量(整个程序运行过程中,只有一份)17 static id _instace;18 //单例模式:设计19 //(1)永远只分配一块内存来创建对象20 //(2)提供一个类方法,返回内部唯一的一个变量21 //(3)最好保证init方法也只初始化一次22 23 //构造方法24 -(id)init25 {26 // __block id obj=nil;27 static id obj=nil;28 static dispatch_once_t onceToken;29 dispatch_once(&onceToken, ^{30 if ((obj=[super init]) != nil) {31 //加载所需的音乐资源32 //....33 // self.muscis=[NSMutableDictionary dictionary];34 // self.muscis[@"1.mp3"]=1mp3数据;35 // self.muscis[@"2.mp3"]=2mp3数据;36 }37 });38 self=obj;39 40 return self;41 }42 43 44 //重写该方法,控制内存的分配,永远只分配一次存储空间45 +(id)allocWithZone:(struct _NSZone *)zone46 {47 48 //里面的代码只会执行一次49 static dispatch_once_t onceToken;50 dispatch_once(&onceToken, ^{51 _instace=[super allocWithZone:zone];52 });53 return _instace;54 }55 56 //类方法57 +(id)sharedAudioTool58 {59 //里面的代码永远都只执行一次60 static dispatch_once_t onceToken;61 dispatch_once(&onceToken, ^{62 _instace=[[self alloc]init];63 });64 return _instace;65 }66 67 +(id)copyWithZone:(struct _NSZone *)zone68 {69 return _instace;70 }71 @end
YYAudioTool.h文件
1 #import <Foundation/Foundation.h>2 3 @interface YYAudioTool : NSObject4 //提供一个类方法,返回内部唯一的一个变量5 +(id)sharedAudioTool;6 @end
主控制器中创建对象:
1 // 2 // YYViewController.m 3 // 06-单例模式1 4 // 5 // Created by apple on 14-6-25. 6 // Copyright (c) 2014年 itcase. All rights reserved. 7 // 8 9 #import "YYViewController.h"10 #import "YYAudioTool.h"11 12 @interface YYViewController ()13 14 @end15 16 @implementation YYViewController17 18 - (void)viewDidLoad19 {20 [super viewDidLoad];21 // YYAudioTool *tool1=[[YYAudioTool alloc]init];22 // YYAudioTool *tool2=[[YYAudioTool alloc]init];23 YYAudioTool *tool1=[YYAudioTool sharedAudioTool];24 YYAudioTool *tool2=[YYAudioTool sharedAudioTool];25 YYAudioTool *tool3=[[YYAudioTool alloc]init];26 YYAudioTool *tool4=[[YYAudioTool alloc]init];27 NSLog(@"%p--%p--%p--%p",tool1,tool2,tool3,tool4);28 }29 30 @end
观察打印结果:
说明:整个程序中只创建一个对象实例。
4.static补充:
注意:static id instace=nil;和static id instace;instace=nil;的区别