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

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

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

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

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

打印结果:

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

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

1.新的困扰

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

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

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

条件编译的使用:

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

新建一个.h头文件

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

 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)

时间: 2024-10-31 14:46:00

iOS开发多线程篇—单例模式(MRC)的相关文章

iOS开发多线程篇—单例模式(ARC) - 文顶顶

原文  http://www.cnblogs.com/wendingding/p/3808641.html iOS开发多线程篇—单例模式(ARC) 一.简单说明: 设计模式:多年软件开发,总结出来的一套经验.方法和工具 java中有23种设计模式,在ios中最常用的是单例模式和代理模式. 二.单例模式说明 (1)单例模式的作用 :可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问,从而方便地控制了实例个数,并节约系统资源. (2)单例模式的使用场合:在整个应用程序中,共享一份资

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

iOS开发多线程篇—单例模式(ARC) - 文顶顶 原文  http://www.cnblogs.com/wendingding/p/3808641.html iOS开发多线程篇—单例模式(ARC) 一.简单说明: 设计模式:多年软件开发,总结出来的一套经验.方法和工具 java中有23种设计模式,在ios中最常用的是单例模式和代理模式. 二.单例模式说明 (1)单例模式的作用 :可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问,从而方便地控制了实例个数,并节约系统资源. (

iOS开发多线程篇—线程的状态

iOS开发多线程篇—线程的状态 一.简单介绍 线程的创建: self.thread=[[NSThread alloc]initWithTarget:self selector:@selector(test) object:nil]; 说明:创建线程有多种方式,这里不做过多的介绍. 线程的开启: [self.thread start]; 线程的运行和阻塞: (1)设置线程阻塞1,阻塞2秒 [NSThread sleepForTimeInterval:2.0]; (2)第二种设置线程阻塞2,以当前时

iOS开发多线程篇—自定义NSOperation

iOS开发多线程篇—自定义NSOperation 一.实现一个简单的tableView显示效果 实现效果展示: 代码示例(使用以前在主控制器中进行业务处理的方式) 1.新建一个项目,让控制器继承自UITableViewController. 1 // 2 // YYViewController.h 3 // 01-自定义Operation 4 // 5 // Created by apple on 14-6-26. 6 // Copyright (c) 2014年 itcase. All rig

iOS开发多线程篇 09 —NSOperation简单介绍

iOS开发多线程篇—NSOperation简单介绍 一.NSOperation简介 1.简单说明 NSOperation的作?:配合使用NSOperation和NSOperationQueue也能实现多线程编程 NSOperation和NSOperationQueue实现多线程的具体步骤: (1)先将需要执行的操作封装到一个NSOperation对象中 (2)然后将NSOperation对象添加到NSOperationQueue中 (3)系统会?动将NSOperationQueue中的NSOpe

iOS开发多线程篇 05 —GCD介绍

iOS开发多线程篇—GCD介绍 一.简单介绍 1.什么是GCD? 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数 2.GCD的优势 GCD是苹果公司为多核的并行运算提出的解决方案 GCD会自动利用更多的CPU内核(比如双核.四核) GCD会自动管理线程的生命周期(创建线程.调度任务.销毁线程) 程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码 3.提示 (1)GCD存在于libdispatch.dylib这个库中

iOS开发多线程篇—多线程简单介绍

iOS开发多线程篇—多线程简单介绍 一.进程和线程 1.什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开QQ.Xcode,系统就会分别启动2个进程 通过“活动监视器”可以查看Mac系统中所开启的进程 2.什么是线程 1个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程) 线程是进程的基本执行单元,一个进程(程序)的所有任务都在线程中执行 比如使用酷狗播放音乐.使用迅雷下载电影,都需要在线程中执行 3.线程

iOS开发多线程篇—多线程的的相关概念(1)

iOS开发多线程篇-多线程简单介绍 一.进程和线程 1.什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开QQ.Xcode,系统就会分别启动2个进程 通过"活动监视器"可以查看Mac系统中所开启的进程 2.什么是线程 1个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程) 线程是进程的基本执行单元,一个进程(程序)的所有任务都在线程中执行 比如使用酷狗播放音乐.使用迅雷下载电影,都需要在线程中执行

iOS开发多线程篇—GCD的基本使用

iOS开发多线程篇—GCD的基本使用 一.主队列介绍 主队列:是和主线程相关联的队列,主队列是GCD自带的一种特殊的串行队列,放在主队列中得任务,都会放到主线程中执行. 提示:如果把任务放到主队列中进行处理,那么不论处理函数是异步的还是同步的都不会开启新的线程. 获取主队列的方式: dispatch_queue_t queue=dispatch_get_main_queue(); (1)使用异步函数执行主队列中得任务,代码示例: 1 // 2 // YYViewController.m 3 //