『ios』设计模式—单例模式(严格单例)

单例模式我们平时经常使用,这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
有几个非常重要的问题。

单例类只能有一个实例。
单例类必须自己创建自己的唯一实例。
单例类必须给所有其他对象提供这一实例。

其实我们在平时项目中,很少注意,如何避免子类继承我们的单例类。
如何来实现一个严格的单例
我们平时是这么使用的。

  static UserInfoManagerCenter *center = nil;
+ (instancetype)managerCenter {
     static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        center = [[UserInfoManagerCenter alloc] init];
    });
    return center;
}

那么如何避免子类继承我们,避免使用init方法来创建对象呢?
我们可以在dispatch_once外面做下判断,如何他使用了继承,调用了managerCenter直接崩溃。

  static UserInfoManagerCenter *center = nil;
+ (instancetype)managerCenter {
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        center = (UserInfoManagerCenter *)@"UserInfoManagerCenter";
        center = [[UserInfoManagerCenter alloc] init];
    });
    //防止子类使用
    if (![NSStringFromClass([self class]) isEqualToString:@"UserInfoManagerCenter"]) {
        //#define NSParameterAssert(condition) NSAssert((condition), @"Invalid parameter not satisfying: %@", @#condition)
        //ios 是这么定义NSParameterAssert的
        //传入nil会导致app崩溃
        NSParameterAssert(nil);
    }
    return center;
}

那么如何避免子类调用父类的init方法来创建对象呢?
重写父类的init方法,同样如果是子类调用父类的init方法,直接崩溃

- (instancetype)init {
    NSString *string = (NSString *)center;
    if ([string isKindOfClass:[NSString class]] == YES && [string isEqualToString:@"UserInfoManagerCenter"]) {
        self = [super init];
        if (self) {
            // 防止子类使用
            NSString *classString = NSStringFromClass([self class]);
            if (![classString isEqualToString:@"UserInfoManagerCenter"]) {
                NSParameterAssert(nil);
            }
        }
        return self;
    } else {
        return nil;
    }
}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容