单粒设计模式

需求:当某些情况下,我们可能需要项目中,其中某一个类不管是任何地方都需要只有一个相同的地址,那么这个时候需要单粒设计模式

单粒设计模式第一步

首先自定义一个类
#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

results matching ""

    No results matching ""