1.为什么再谈?
常规的单例写法有两种
+ (Student *)defaultInstance
{
static Student *defaultInstance = nil;
if (!defaultInstance)
{
defaultInstance = [[self alloc] init];
}
return defaultInstance;
}
或
+ (Student *)sharedManager
{
static Student *sharedInstance = nil;
static dispatch_once_t predicate;//此象必须是全局或者静态对象才能保证唯一性
dispatch_once(&predicate, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
这两种写法的优缺点都是老生常谈,本文不再赘述。
这两种写法的最大问题其实是不能保证别人只通过这种方式获取该对象。若直接使用Student *std = [Student alloc] init];
的方式去创建对象,则获取到的是一个新的对象。
2.解决方案
模仿UIApplication
重写init
方法。调用init
时抛出异常,禁止别人调用。
-
在.m文件中
static Student *student = nil;+ (void)load { student = [[self alloc] init]; } //此方法和load选一个写即可,两个方法的区别下篇文章讲 //+ (void)initialize //{ // student = [[self alloc] init]; //} + (instancetype)shareInstance { return student; } - (instancetype)init { if (student) { //抛异常 NSException *exp = [NSException exceptionWithName:NSInternalInconsistencyException reason:@"There can only be one Student instance." userInfo:nil]; [exp raise]; } return [super init]; }
如这样处理,在调用init
时会抛出异常。
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'There can only be one Student instance.'
.
.//省略无关内容
.
libc++abi.dylib: terminating with uncaught exception of type NSException