单例模式我们平时经常使用,这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
有几个非常重要的问题。
单例类只能有一个实例。
单例类必须自己创建自己的唯一实例。
单例类必须给所有其他对象提供这一实例。
其实我们在平时项目中,很少注意,如何避免子类继承我们的单例类。
如何来实现一个严格的单例
我们平时是这么使用的。
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;
}
}