单例模式
@synchronized
1,定义一个静态的全局的变量
staticSettings *sharedSettings = nil;
2,创建一个类方法,用来返回该类实例
synchronized 这个主要是考虑多线程的程序,这个指令可以将{ } 内的代码限制在一个线程执行,如果某个线程没有执行完,其他的线程如果需要执行就得等着。
+ (Settings *)sharedInstance { @synchronized(self){ if(sharedSettings == nil){ sharedSettings = [[self alloc] init]; //做一些初始化操作 } } return sharedSettings; }
3,重写allocWithZone方法,用来保证其他人直接使用alloc和init试图获得一个新实力的时候不产生一个新实例,
+ (id)allocWithZone:(NSZone *)zone { @synchronized(self) { if (sharedSettings == nil) { sharedSettings = [super allocWithZone:zone]; } } return sharedSettings; }
dispatch_once
有些变量只需要初始化一次(如从文件中读取配置参数,读取设备型号等等),可以使用dispatch_once来进行读取优化,保证只调用API一次,以后就只要直接访问变量即可
void dispatch_once( dispatch_once_t *predicate, dispatch_block_t block);
dispatch_once不仅意味着代码仅会被运行一次,而且还是线程安全的,这就意味着你不需要使用诸如@synchronized之类的来防止使用多个线程或者队列时不同步的问题。
//范例如下: static BOOL isTestMode; + (BOOL)isTestMode { staticdispatch_once_tonceToken; dispatch_once(&onceToken, ^{ NSNumber* obj = [[[NSBundle mainBundle]infoDictionary] objectForKey:@"CFResourceTest"]; isTestMode= [obj boolValue]; }); return isTestMode; }
实际要如何使用这些呢?
好吧,假设有一个AccountManager类,你想在整个应用中访问该类的共享实例。你可以按如下代码简单实现一个类方法:
+ (AccountManager *)sharedManager { static AccountManager *sharedAccountManagerInstance =nil; static dispatch_once_tpredicate; dispatch_once(&predicate, ^{ sharedAccountManagerInstance = [[self alloc] init]; }); return sharedAccountManagerInstance; }
这就意味着你任何时候访问共享实例,需要做的仅是:
AccountManager*accountManager=[AccountManagersharedManager];
就这些,你现在在应用中就有一个共享的实例,该实例只会被创建一次。
该方法有很多优势:
1 线程安全
2 很好满足静态分析器要求
3 和自动引用计数(ARC)兼容
4 仅需要少量代码
该方法的劣势就是它仍然运行创建一个非共享的实例