1.系統(tǒng)中常用單例
[[UIApplication sharedApplication] statusBarStyle];
[NSNotificationCenter defaultCenter];
[NSUserDefaults standardUserDefaults];
[NSFileManager defaultManager];
單例模式中近顷,一般用于管理某對(duì)象持有資源鞋喇,可以全局共享窃页。
大部分使用單例模式共享信息啤覆。
2.單例使用
2.1.創(chuàng)建
2.1.1常規(guī)方式
聲明一個(gè)靜態(tài)變量持有對(duì)象
static ManageViewController *center = nil;
if (center == nil) {
center = [[ManageViewController alloc] init];
}
return center;
存在問題:可能AppDlegate與ViewController訪問時(shí)徙鱼,同時(shí)進(jìn)入center = [[ManageViewController alloc] init];
2.1.2.使用dispatch_once 避免上述問題(最佳)
static ManageViewController *center = nil;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
center = [[ManageViewController alloc] init];
});
return center;
2.1.3.使用initialize方法
每個(gè)類調(diào)用任意方法時(shí)宅楞,都會(huì)先調(diào)用initialize
+(void)initialize{
static ManageViewController *center = nil;
if (self == [ManageViewController class]) {
center = [[ManageViewController alloc] init];
}
}
2.2.創(chuàng)建單例注意
2.2.1防止其他類調(diào)用
+(instancetype)manageCenter{
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
center = (ManageViewController *)@"ManageViewController";
center = [[ManageViewController alloc] init];
});
//防止子類使用
NSString *classString = NSStringFromClass([self class]);//獲取當(dāng)前類名
if ([classString isEqualToString:@"ManageViewController"] == NO) {
NSParameterAssert(nil);//如果不符合,此處崩潰提示:Invalid parameter not satisfying:nil
}
return center;
}
2.2.2.保證只有一個(gè)實(shí)例對(duì)象
一個(gè)單例類作為管理中心袱吆,系統(tǒng)開銷很大咱筛。實(shí)例化一個(gè)對(duì)象,消耗很大杆故。
重寫init方法
+(instancetype)manageCenter{
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
center = (ManageViewController *)@"ManageViewController";
center = [[ManageViewController alloc] init];
});
//防止子類使用
NSString *classString = NSStringFromClass([self class]);//獲取當(dāng)前類名
if ([classString isEqualToString:@"ManageViewController"] == NO) {
NSParameterAssert(nil);
}
return center;
}
-(instancetype)init{
NSString *string = (NSString *)center;
//判斷string是否為字符串類型以及是否等于給定字符串
if ([string isKindOfClass:[NSString class]] == YES && [string isEqualToString:@"ManageViewController"]) {
self = [super init];
if (self) {
//防止子類使用
NSString *classString = NSStringFromClass([self class]);
if ([classString isEqualToString:@"ManageViewController"] == NO) {
NSParameterAssert(nil);
}
}
return self;
}else{
return nil;
}
}
若是子類執(zhí)行alloc init方法迅箩,此時(shí)center值為空,不符合if條件处铛,返回空饲趋。
執(zhí)行manageCenter方法時(shí),單例對(duì)象(center)指向字符串撤蟆。開始執(zhí)行init奕塑,符合判斷條件,實(shí)例化對(duì)象家肯。而之后執(zhí)行alloc init時(shí)龄砰,center值變?yōu)镸anageViewController值,不符合if中判斷條件讨衣,返回nil换棚。
3.本地存儲(chǔ)優(yōu)化
使用第三方“FastCoder”.也可使用官方方法(遵守NSCoding協(xié)議) :
- (void)encodeWithCoder:(NSCoder *)aCoder;
- (nullable instancetype)initWithCoder:(NSCoder*)aDecoder;
3.1.用單例設(shè)計(jì)存儲(chǔ)數(shù)據(jù)接口,用單例接口隔離實(shí)現(xiàn)細(xì)節(jié)
StoreValue.m中
+(ManageValue *)sharedInstance{
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
manageValue = (ManageValue *)@"manage";
manageValue = [[ManageValue alloc] init];
});
//防止子類使用
NSString *classString = NSStringFromClass([self class]);
if ([classString isEqualToString:@"ManageValue"] == NO) {
NSParameterAssert(nil);
}
return manageValue;
}
//保證只有一個(gè)實(shí)例反镇,重寫init 方法
-(instancetype)init{
NSString *string = (NSString *)manageValue;
if ([string isKindOfClass:[NSString class]] == YES && [string isEqualToString:@"manage"]) {
self = [super init];
if (self) {
//防止子類使用
NSString *classString = NSStringFromClass([self class]);
NSLog(@"%@",classString);
if ([classString isEqualToString:@"ManageValue"] == NO) {
NSParameterAssert(nil);
}
}
return self;
}else{
return nil;
}
}
-(void)storeValue:(id)value withKey:(NSString *)key{
//value固蚤、key值不能為空
NSParameterAssert(value);
NSParameterAssert(key);
//value值轉(zhuǎn)化為NSData,后進(jìn)行存儲(chǔ)
NSData *data = [FastCoder dataWithRootObject:value];
if (data) {
[[NSUserDefaults standardUserDefaults] setObject:data forKey:key];
}
}
-(id)valueWithKey:(NSString *)key{
NSParameterAssert(key);
NSData *data = [[NSUserDefaults standardUserDefaults] valueForKey:key];
return [FastCoder objectWithData:data];
}
測(cè)試一下:
ViewController.m中
StaffModel *model = [[StaffModel alloc] init];
model.name = @"AA";
model.salary = @"1000";
ManageValue *value = [ManageValue sharedInstance];
//存值
[value storeValue:model withKey:@"data"];
StaffModel *temp = [[StaffModel alloc] init];
//取值
temp = [value valueForKey:@"data"];
NSLog(@"%@",temp.name);
輸出得到值歹茶。
3.2.在單例提供的接口上實(shí)現(xiàn)上層封裝
好處:
把實(shí)現(xiàn)細(xì)節(jié)隔離夕玩。如果要修改存儲(chǔ)方案你弦,只需要修改實(shí)現(xiàn)方法中的細(xì)節(jié)。改動(dòng)少燎孟。
創(chuàng)建一個(gè)分類禽作,添加方法
-(void)storeValueByKey:(NSString *)key{
[[ManageValue sharedInstance] storeValue:self withKey:key];
}
+(id)getValueWithKey:(NSString *)key{
return [[ManageValue sharedInstance] valueForKey:key];
}
ViewController.m中
[model storeValueByKey:@"data"];
StaffModel *temp = [StaffModel getValueWithKey:@"data"];
NSLog(@"%@",temp.name);
聲明:參考網(wǎng)絡(luò)資源,若侵權(quán)揩页,請(qǐng)告知领迈。