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 *)zone
2 {    @synchronized(self) {
3         if (!_instance) {
4             _instance = [super allocWithZone:zone];
5         }
6     }
7     return _instance;
8 } 

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

1 + (instancetype)sharedSoundTool
2 {
3     @synchronized(self) {
4         if (!_instance) {
5             _instance = [[self alloc] init];
6         }
7     }
8     return _instance;
9 }

3)实现copyWithZone:方法

1 + (id)copyWithZone:(struct _NSZone *)zone
2 {
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 @end
14 @implementation YYAudioTool
15 //构造方法
16 -(id)init
17 {
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)alloc
30 {
31     NSLog(@"alloc----");
32     return [super alloc];
33 }
34 
35 //控制内存分配,每次调用allocWithzone:方法,系统都会创建一块新的内存空间
36 +(id)allocWithZone:(struct _NSZone *)zone
37 {
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 @end
15 
16 @implementation YYViewController
17 
18 - (void)viewDidLoad
19 {
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 @end
14 
15 @implementation YYAudioTool
16 //定义一份变量(整个程序运行过程中,只有一份)
17 static id _instace;
18 //单例模式:设计
19 //(1)永远只分配一块内存来创建对象
20 //(2)提供一个类方法,返回内部唯一的一个变量
21 //(3)最好保证init方法也只初始化一次
22 
23 //构造方法
24 -(id)init
25 {
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 *)zone
46 {
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)sharedAudioTool
58 {
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 *)zone
68 {
69     return _instace;
70 }
71 @end

YYAudioTool.h文件

1 #import <Foundation/Foundation.h>
2 
3 @interface YYAudioTool : NSObject
4 //提供一个类方法,返回内部唯一的一个变量
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 @end
15 
16 @implementation YYViewController
17 
18 - (void)viewDidLoad
19 {
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;的区别

posted on 2015-05-03 19:49  iosblog's  阅读(1497)  评论(0编辑  收藏  举报

导航