一、簡單說明:
設計模式:多年軟件開發,總結出來的一套經驗、方法和工具
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