单例模式的ARC和MRC实现

单例在整个工程中,就相当于一个全局变量,就是不论在哪里需要用到这个类的实例变量,都可以通过单例方法来取得,而且一旦你创建了一个单例类,不论你在多少个界面中初始化调用了这个单例方法取得对象,它们所有的对象都是指向的同一块内存存储空间(即单例类保证了该类的实力对象是唯一存在的一个).

单例模式的作用

  1. 可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问
  2. 从而方便地控制了实例个数,并节约系统资源
  • ARC中,单例模式的实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 提供1个类方法让外界访问唯一的实例
+ (instancetype)sharedTools
{
return [[self alloc] init];
}
// 在.m中保留一个全局的static的实例
static Tools *_instance;
// 重写allocWithZone:方法,在这里创建唯一的实例
// 注意线程安全,判断是否为nil,可能多次创建
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
return _instance;
}
// 实现copyWithZone:方法
- (id)copyWithZone:(struct _NSZone *)zone
{
// 因为copy方法必须通过实例对象调用,所以可以直接返回_instance
return _instance;
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
return _instance;
}
  • MRC中,单例模式的实现
除了添加上面ARC实现的代码,再添加下面代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#pragma mark - MRC
#if __has_feature(objc_arc)
// 如果是ARC什么都不添加
#else
- (oneway void)release
{
}
- (instancetype)retain
{
return _instance;
}
- (NSUInteger)retainCount
{
return MAXFLOAT; //装逼格
}
#endif
单例不能继承,类的静态变量只被初始化一次,子类和父类谁先调用,创建的就是哪种类型的变量,以后也不会改变

创建很多单例

  • 利用宏定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//
// Single.h
// 01-掌握-单例ARC
//
// Created by apple on 15/8/6.
// Copyright (c) 2015年 CoderShmily. All rights reserved.
//
#define interfaceSingle(name) + (instancetype)share##name
#if __has_feature(objc_arc)
// 如果是ARC
#define implementationSingle(name) + (instancetype)share##name \
{ \
return [[self alloc] init]; \
} \
static id _instance; \
+ (instancetype)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [super allocWithZone:zone]; \
}); \
return _instance; \
} \
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instance; \
} \
- (id)mutableCopyWithZone:(NSZone *)zone \
{ \
return _instance; \
}
#else
// 如果不是ARC
#define implementationSingle(name) + (instancetype)share##name \
{ \
return [[self alloc] init]; \
} \
static id _instance; \
+ (instancetype)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [super allocWithZone:zone]; \
}); \
return _instance; \
} \
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instance; \
} \
- (id)mutableCopyWithZone:(NSZone *)zone \
{ \
return _instance; \
}\
- (oneway void)release \
{} \
- (instancetype)retain \
{ \
return _instance; \
} \
- (NSUInteger)retainCount \
{ \
return MAXFLOAT; \
}
#endif
  • 使用宏定义
1
2
3
4
5
6
7
8
9
// FileTools.h
#import <Foundation/Foundation.h>
#import "Single.h"
@interface FileTools : NSObject
//+ (instancetype)shareFileTools;
interfaceSingle(FileTools);
@end
1
2
3
4
5
6
7
8
9
// FileTools.m
#import "FileTools.h"
@implementation FileTools
implementationSingle(FileTools)
@end