iOS 单例模式 - 单例对象销毁【GCD】

单例对象的创建方式

单例.h 文件的实现

#import 

NS_ASSUME_NONNULL_BEGIN

@interface NBNetworkTools : NSObject

// 创建单例对象
+ (instancetype)sharedInstance;

// 销毁单例对象
- (void)dellocInstance;

// 用户名
@property (nonatomic,copy) NSString *username;

// 密码
@property (nonatomic,copy) NSString *password;

@end

NS_ASSUME_NONNULL_END

单例的.m 文件的实现

#import "NBNetworkTools.h"

@implementation NBNetworkTools

static NBNetworkTools *sharedInstance = nil;
static dispatch_once_t onceToken;
+ (instancetype)sharedInstance {
    dispatch_once(&onceToken, ^{
        // 使用super 调用父类等 allocWithZone,避免循环引用
        // 因为重写了 allocWithZone 返回的是 [self sharedInstance], 如果调用了 [self allocWithZone], 就会出现循环调用的问题,规避循环引用使用 super 进行初始化
        sharedInstance = [[super allocWithZone:NULL]init];
    });
    return sharedInstance;
}

// 【必不可少】重写 allocWithZone 方法
// 因为不使用 sharedInstance 进行创建对象的情况,也是有可能的
// 比如使用 alloc 进行创建, alloc 会调用 allocWithZone ,所以重写 allocWithZone,在内部手动调用 [self sharedInstance];
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    return [self sharedInstance];
}

// 【必不可少】当单例被 copy
// 外界有可能会对当前实例进行copy操作来创建一个对象,要保证一个对象在App生命周期内永远只能被创建一次,我们还需要重写 copyWithZone 方法
// 直接将 self 返回就可以了
- (id)copyWithZone:(nullable NSZone *)zone {
    return self;
}


// 销毁单例对象
- (void)dellocInstance {
    // 设置为0,GCD会认为它从未执行过,这样才能保证下次调用 shareInstance 的时候,再次创建对象
    onceToken = 0;
    sharedInstance = nil;
}

单例对象的销毁【GCD创建的方式】

使用单例对象的时候,如果我们暂时不用这个对象,同时想释放单例占用的内存空间,所以我们需要把它销毁掉,用的时候在创建出来,那怎么做呢?
上面的代码是包含这部分功能的,操作的方式就是在销毁的方法里面:把 onceToken = 0; 设置为0,此时我们的GCD就会认为这个block没有执行过,就会再次执行Block内的代码

  • 可以通过打印观察 onceToken 的值的变化,就可以发现了
  • 下面是销毁的代码
// 销毁单例对象
- (void)dellocInstance {
    // 设置为0,GCD会认为它从未执行过,这样才能保证下次调用 shareInstance 的时候,再次创建对象
    onceToken = 0;
    sharedInstance = nil;
}

参考:
iOS单例模式对象的创建及销毁

你可能感兴趣的:(iOS 单例模式 - 单例对象销毁【GCD】)