单粒设计模式
需求:当某些情况下,我们可能需要项目中,其中某一个类不管是任何地方都需要只有一个相同的地址,那么这个时候需要单粒设计模式
单粒设计模式第一步
首先自定义一个类
#import "JXPerson.h"
@implementation JXPerson
// 先定义一个属性,用来保存实例化的对象
static JXPerson *_person;
// 重写alloc方法
// 不管是alloc,还是allocWithZone,来分配空间最后都是调用这个方法
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_person = [super allocWithZone:zone];
});
return _person;
}
@end
这样,不管之后在什么类中,调用[[JXPerson alloc] init]多少次,永远都会取得同一个对象
在别的类中调用一个
#import "ViewController.h"
#import "JXPerson.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
JXPerson * person1 = [[JXPerson alloc] init];
JXPerson * person2 = [[JXPerson alloc] init];
JXPerson * person3 = [[JXPerson alloc] init];
JXPerson * person4 = [[JXPerson alloc] init];
NSLog(@"%p = %p = %p = %p",person1,person2,person3,person4);
}
@end
打印结果:
2016-05-29 10:51:45.882 JXSingle[809:28725] 0x7f9543c23f90 = 0x7f9543c23f90 = 0x7f9543c23f90 = 0x7f9543c23f90
结果都是相同的
当然上面直接自定义的一个类是有一点不合适的地方,一般我们使用单粒的时候都是有直接的类方法,比如苹果的UIApplication都是有的,所以我们还需要重写写一个类方法;
为自定义的类添加类方法
JXPerson.h
#import <Foundation/Foundation.h>
@interface JXPerson : NSObject
// 创建一个类方法
+ (instancetype)sharePerson;
@end
JXPerson.m
#import "JXPerson.h"
@implementation JXPerson
// 先定义一个属性,用来保存实例化的对象
static JXPerson *_person;
// 重写alloc方法
// 不管是alloc,还是allocWithZone,来分配空间最后都是调用这个方法
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_person = [super allocWithZone:zone];
});
return _person;
}
+ (instancetype)sharePerson {
// 这个方法只会执行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_person = [[self alloc] init];
});
return _person;
}
@end
上面的方法虽然已经有了比较完善的方法,但是还是不够完美,因为我们不能阻止人家使用copy
JXPerson.h
#import "JXPerson.h"
@interface JXPerson () <NSCopying>
@end
@implementation JXPerson
// 先定义一个属性,用来保存实例化的对象
static JXPerson *_person;
// 重写alloc方法
// 不管是alloc,还是allocWithZone,来分配空间最后都是调用这个方法
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_person = [super allocWithZone:zone];
});
return _person;
}
+ (instancetype)sharePerson {
// 这个方法只会执行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_person = [[self alloc] init];
});
return _person;
}
- (id)copyWithZone:(NSZone *)zone {
return _person;
}
@end