码迷,mamicode.com
首页 > 移动开发 > 详细

iOS开发多线程篇—单例模式(MRC)

时间:2014-06-26 17:37:18      阅读:366      评论:0      收藏:0      [点我收藏+]

标签:style   class   blog   code   http   color   

iOS开发多线程篇—单例模式(MRC)

 一、非ARC模式下的单例模式

1.说明:把一个项目修改为非ARC的

bubuko.com,布布扣

2.MAC下单例模式代码示例:

新建一个工具类,让该类继承自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     });
34     self=obj;
35 
36     return self;
37 }
38 
39 
40 //重写该方法,控制内存的分配,永远只分配一次存储空间
41 +(id)allocWithZone:(struct _NSZone *)zone
42 {
43 
44     //里面的代码只会执行一次
45     static dispatch_once_t onceToken;
46     dispatch_once(&onceToken, ^{
47         _instace=[super allocWithZone:zone];
48     });
49     return _instace;
50 }
51 
52 //类方法
53 +(id)sharedAudioTool
54 {
55   //里面的代码永远都只执行一次
56     static dispatch_once_t onceToken;
57     dispatch_once(&onceToken, ^{
58         _instace=[[self alloc]init];
59     });
60     return _instace;
61 }
62 
63 //重写release方法
64 //oneway :分布式对象
65 -(oneway void)release
66 {
67 }
68 
69 //不管调用哪个方法,返回的都是唯一的实例,所以这里self和instace是一样的
70 -(id)autorelease
71 {
72     return self;
73 }
74 
75 -(id)retain
76 {
77     return self;
78 }
79 
80 -(NSUInteger)retainCount
81 {
82     return 1;
83 }
84 
85 +(id)copyWithZone:(struct _NSZone *)zone
86 {
87     return _instace;
88 }
89 @end

YYAudioTool.h文件

 1 //
 2 //  YYAudioTool.h
 3 //  06-单例模式1
 4 //
 5 //  Created by apple on 14-6-25.
 6 //  Copyright (c) 2014年 itcase. All rights reserved.
 7 //
 8 
 9 #import <Foundation/Foundation.h>
10 
11 @interface YYAudioTool : NSObject
12 //提供一个类方法,返回内部唯一的一个变量
13 +(id)sharedAudioTool;
14 @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 sharedAudioTool];
22     YYAudioTool *tool2=[YYAudioTool sharedAudioTool];
23     YYAudioTool *tool3=[YYAudioTool sharedAudioTool];
24     YYAudioTool *tool4=[[YYAudioTool alloc]init];
25     
26     NSLog(@"%p--%p--%p--%p",tool1,tool2,tool3,tool4);
27     
28     //对象创建只会,release对象会销毁,无法再创建新的对象(因为单例),所以还需要重写release方法
29     [tool1 release];
30     [tool2 release];
31     [tool3 release];
32     [tool4 release];
33 }
34 
35 @end

打印结果:

bubuko.com,布布扣

说明:整个程序过程中,只创建一个对象实例。

 

 二、把单例代码定义为一个带参数的宏

1.新的困扰

弊端:如果又创建一个新的类,是否又要把文件代码拷贝一份,所以这里可以考虑把固定的代码写成宏。

由于项目中代码经常有移植的需要,要求项目中又有ARC的,又有非ARC的,应该怎么应用单例模式?

不管项目是ARC的还是非ARC的,这个宏都有用。可以先判断编译器的环境,判断当前环境是否是ARC的。

条件编译的使用:

bubuko.com,布布扣

2.使用条件编译,并把单例模式的代码定义为宏。

新建一个.h头文件

bubuko.com,布布扣

  把代码定义为宏,头文件中的代码如下:

 1 // ## : 连接字符串和参数
 2 #define singleton_h(name) + (instancetype)shared##name;
 3 
 4 #if __has_feature(obj_arc)  //如果是ARC
 5 #define singleton_m(name)  6 static id _instance;  7 + (id)allocWithZone:(struct _NSZone *)zone  8 {  9     static dispatch_once_t onceToken; 10     dispatch_once(&onceToken, ^{ 11         _instance = [super allocWithZone:zone]; 12     }); 13     return _instance; 14 } 15 16 + (instancetype)shared##name 17 { 18     static dispatch_once_t onceToken; 19     dispatch_once(&onceToken, ^{ 20         _instance = [[self alloc] init]; 21     }); 22     return _instance; 23 } 24 25 + (id)copyWithZone:(struct _NSZone *)zone 26 { 27     return _instance; 28 }
29 
30 #else //非ARC
31 #define singleton_m(name) 32 static id _instance; 33 + (id)allocWithZone:(struct _NSZone *)zone 34 { 35     static dispatch_once_t onceToken; 36     dispatch_once(&onceToken, ^{ 37         _instance = [super allocWithZone:zone]; 38     }); 39     return _instance; 40 } 41  42 + (instancetype)shared##name 43 { 44     static dispatch_once_t onceToken; 45     dispatch_once(&onceToken, ^{ 46         _instance = [[self alloc] init]; 47     }); 48     return _instance; 49 } 50  51 - (oneway void)release 52 { 53  54 } 55  56 - (id)autorelease 57 { 58     return _instance; 59 } 60  61 - (id)retain 62 { 63     return _instance; 64 } 65  66 - (NSUInteger)retainCount 67 { 68     return 1; 69 } 70  71 + (id)copyWithZone:(struct _NSZone *)zone 72 { 73     return _instance; 74 }
75 #endif

在程序中的应用:

控制器问价代码如下:

 1 #import "YYViewController.h"
 2 #import "YYAudioTool.h"
 3 
 4 @interface YYViewController ()
 5 
 6 @end
 7 
 8 @implementation YYViewController
 9 
10 - (void)viewDidLoad
11 {
12     [super viewDidLoad];
13     YYAudioTool *tool1=[YYAudioTool sharedAudioTool];
14     
15     //对象创建后,需要考虑
16 //    (1)alloc init
17 //    (2)release
18 //    (3)copy copy内部会调用另外一个方法copywithzone
19 //    (4)autorelease
20 //    
21     YYAudioTool *tool2=[YYAudioTool sharedAudioTool];
22     YYAudioTool *tool3=[YYAudioTool sharedAudioTool];
23     NSLog(@"%p---%p---%p",tool1,tool2,tool3);
24     [tool2 release];
25     [tool3 release];
26     [tool1 release];
27 
28 }
29 
30 @end

工具类的头文件代码如下:

 1 //
 2 //  YYAudioTool.h
 3 //  06-单例模式1
 4 //
 5 //  Created by apple on 14-6-25.
 6 //  Copyright (c) 2014年 itcase. All rights reserved.
 7 //
 8 
 9 #import <Foundation/Foundation.h>
10 #import "Singleton.h"
11 
12 @interface YYAudioTool : NSObject
13 ////提供一个类方法,返回内部唯一的一个变量
14 //+(id)sharedAudioTool;
15 singleton_h(AudioTool)
16 @end

工具类的实现部分代码如下:

 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 //构造方法
20 -(id)init
21 {
22 //    __block id obj=nil;
23     static id obj=nil;
24     static dispatch_once_t onceToken;
25     dispatch_once(&onceToken, ^{
26         if ((obj=[super init]) != nil) {
27 //........
28         }
29     });
30     self=obj;
31     return self;
32 }
33 
34 singleton_m(AudioTool)
35 @end

补充说明:如果把代码下载dispatch_once里面,那么它内部默认会进行加锁。

 

三、补充

问题:ARC和非ARC单例模式的区别?

由于非ARC是进行手动内存管理,所以需要注意下面一个方法,在项目中通常使用宏。

- (id)retain { return self; }

- (NSUInteger)retainCount { return 1; }

- (oneway void)release {}

- (id)autorelease { return self; }

iOS开发多线程篇—单例模式(MRC),布布扣,bubuko.com

iOS开发多线程篇—单例模式(MRC)

标签:style   class   blog   code   http   color   

原文地址:http://www.cnblogs.com/wendingding/p/3808691.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!