什么是单例
什么是单例模式:(Singleton)
单例模式的意图是是的类的对象成为系统中唯一的实例,供一个访问点,供客户类 共享资源
单例的使用场景
1.类只能有一个实例,而且必须从一个为人熟知的访问点对其进行访问,比如工厂方法
2.这个唯一的实例只能通过子类化进行扩展,而且扩展的对象不会破坏客户端代码
单例设计模式的要点:
1. 某个类只能有一个实例。
2.他必须自行创建这个对象
3.必须自行向整个系统供这个实例;
4.为了保证实例的唯一性,我们必须将
5.这个方法必须是一个静态类
代码实现:
Tools.h
//
// Person.h
// 练习2
//
// Created by king on 15/11/8.
// Copyright © 2015年 king. All rights reserved.
//
/*
创建一个person的单利对象。使用alloc,copy创建的时候时候只会产生一个对象,并且提供一个单利接入的方法(shareInstance)。
*/
#import <Foundation/Foundation.h>
// 遵守copy协议
@interface Tools : NSObject <NSCopying, NSMutableCopying>
// 一般情况下创建一个单例对象都有一个与之对应的类方法
// 一般情况下用于创建单例对象的方法名称都以share开头, 或者以default开头
+ (instancetype)shareInstance;
@end
Tools.m
#import "Tools.h"
@implementation Tools
+(instancetype)shareInstance {
Tools *instance = [[self alloc] init];
return instance;
}
// 定义一个全局变量
static Tools *_instance = nil;
+(instancetype)allocWithZone:(struct _NSZone *)zone {
/*
// 当前代码在多线程是可能会出现问题
if (_instance == nil) {
// 由于 alloc new copy mutableCopy 创建对象都会调用这个方法
// 所有我们只需要这里控制当前对象只创建一次
_instance = [[super allocWithZone:zone] init];
}
return _instance;
*/
// 当前代码在多线程也能用
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[super allocWithZone:zone] init];
});
return _instance;
}
- (id)copyWithZone:(NSZone *)zone {
return _instance;
}
- (id)mutableCopyWithZone:(NSZone *)zone {
return _instance;
}
@end

而在MRC中 如果调用 release 会发生运行时错误

所以我们需要从写 release retain retainCount
// MRC中
- (oneway void)release {
// 因为只会创建一次 所以我们不能释放当前对象
// 所有这里什么都不做
}
- (instancetype)retain {
return _instance;
}
- (NSUInteger)retainCount {
// 为了程序员之间方便交流 我们一般不写 1
// 而是写一个较大的值,让人一看就知道,这个对象时单例
// return 1;
return MAXFLOAT;
}

利用宏抽取优化代码
Singleton.h
// 以后就可以使用interfaceSingleton来替代后面的方法声明
#define interfaceSingleton(name) +(instancetype)share##name
#if __has_feature(objc_arc)
// ARC
#define implementationSingleton(name) \
+ (instancetype)share##name \
{ \
name *instance = [[self alloc] init]; \
return instance; \
} \
static name *_instance = nil; \
+ (instancetype)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[super allocWithZone:zone] init]; \
}); \
return _instance; \
} \
- (id)copyWithZone:(NSZone *)zone{ \
return _instance; \
} \
- (id)mutableCopyWithZone:(NSZone *)zone \
{ \
return _instance; \
}
#else
// MRC
#define implementationSingleton(name) \
+ (instancetype)share##name \
{ \
name *instance = [[self alloc] init]; \
return instance; \
} \
static name *_instance = nil; \
+ (instancetype)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[super allocWithZone:zone] init]; \
}); \
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
上面的代码 看着是很恶心,但是我只需要恶心一次
Tools.h
#import <Foundation/Foundation.h>
#import "Singleton.h"
// 遵守copy协议
@interface Tools : NSObject <NSCopying, NSMutableCopying>
interfaceSingleton(Tools);
@end
Tools.m
#import "Tools.h"
@implementation Tools
implementationSingleton(Tools)
@end
