1.用單例設(shè)計(jì)存儲數(shù)據(jù)接口
1.1單例接口
+ (AppScene *)sharedInstance;
1.2數(shù)據(jù)序列化接口
- (void)serializeValue:(id)value withKey:(NSString *)key;
1.3數(shù)據(jù)反序列化接口
- (id)deserializeValueWithKey:(NSString *)key;
2.用單例接口隔離實(shí)現(xiàn)細(xì)節(jié)
2.1替代NSCoding協(xié)議
- 在實(shí)現(xiàn)之前先簡單介紹一下fastCoding闯冷,因?yàn)檫^程中會用到fastCoding
fastCoding是用來替代系統(tǒng)的NSCoding的協(xié)議 可以將對象序列化成NSData爱榔,也可以反序列化成對象培愁。 - fastCodin在github鏈接或者在github上搜索fastCoding看到star最多的就是。
-
解壓得到圖中目錄,有用的就只有FastCoder目錄的兩個(gè)文件厨钻,將這兩個(gè)文件加入項(xiàng)目中,編譯會發(fā)現(xiàn)有問題。在ARC下會運(yùn)行的比較slow首繁,可以手動將這個(gè)文件改為MRC環(huán)境,操作如圖陨囊。做完之后弦疮,編譯沒有問題了。
解壓目錄.png
MRC操作.png
2.2數(shù)據(jù)接口的實(shí)現(xiàn)
- 嚴(yán)格單例的實(shí)現(xiàn)(在ios最實(shí)用的13中設(shè)計(jì)模式中的單例模式示例代碼中已經(jīng)詳細(xì)說明了蜘醋,沒有賞光下載觀看的胁塞,可以移步git)
+ (AppScene *)sharedInstance {
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
appScene = (AppScene *)AppSceneString;
appScene = [[AppScene alloc] init];
});
//防止子類使用
if (![NSStringFromClass([self class]) isEqualToString:AppSceneString]) {
NSParameterAssert(nil);
}
return appScene;
}
#pragma mark - private
- (instancetype)init {
NSString *string = (NSString *)appScene;
if ([string isKindOfClass:[NSString class]] == YES && [string isEqualToString:AppSceneString]) {
self = [super init];
if (self) {
// 防止子類使用
NSString *classString = NSStringFromClass([self class]);
if (![classString isEqualToString:AppSceneString]) {
NSParameterAssert(nil);
}
}
return self;
} else {
return nil;
}
}
- 數(shù)據(jù)序列化接口的實(shí)現(xiàn)
- (void)serializeValue:(id)value withKey:(NSString *)key {
NSParameterAssert(value);
NSParameterAssert(key);
//fastCoding是用來地點(diǎn)系統(tǒng)的NSCoding的協(xié)議
//可以將對象序列化成NSData,也可以反序列化對象
NSData *data = [FastCoder dataWithRootObject:value];
if (data) {
[[NSUserDefaults standardUserDefaults] setObject:data forKey:key];
}
}
- 數(shù)據(jù)反序列化接口的實(shí)現(xiàn)
- (id)deserializeValueWithKey:(NSString *)key {
NSParameterAssert(key);
NSData *data = [[NSUserDefaults standardUserDefaults] valueForKey:key];
return [FastCoder objectWithData:data];
}
3.在單例提供接口的基礎(chǔ)上進(jìn)行上層封裝
3.1編寫NSObject的category(storeValue)压语,如圖所示
category.png
3.2category的實(shí)現(xiàn)
- (void)serializeValueWithKey:(NSString *)key {
[[AppScene sharedInstance] serializeValue:self withKey:key];
}
+ (id)deserializeValueWithKey:(NSString *)key {
return [[AppScene sharedInstance] deserializeValueWithKey:key];
}
3.3封裝的優(yōu)點(diǎn)
隔離所有細(xì)節(jié)闲先,假設(shè)以后更改實(shí)現(xiàn)方法,原有代碼無需更改无蜂。
4測試
4.1測試結(jié)果OK伺糠,如圖
測試結(jié)果.png
4.2測試代碼,可以感受封裝優(yōu)點(diǎn)
- (void)test1 {
[[AppScene sharedInstance] serializeValue:@{@"A":@"B"} withKey:@"test"];
NSLog(@"------------test1------------");
NSLog(@"%@", [[AppScene sharedInstance] deserializeValueWithKey:@"test"]);
}
- (void)test2 {
Dog *dog = [[Dog alloc] init];
dog.name = @"旺財(cái)";
dog.identify = @{@"color" : @"black", @"weight" : @"20kg", @"height" : @"50cm"};
[[AppScene sharedInstance] serializeValue:dog withKey:dog.name];
NSLog(@"-----------test2-------------");
Dog *wangcai = [[AppScene sharedInstance] deserializeValueWithKey:@"旺財(cái)"];
NSLog(@"%@", wangcai.identify);
}
//test3在test2的基礎(chǔ)上增加了category,在單例提供接口的基礎(chǔ)上進(jìn)行上層封裝斥季,隔離所有細(xì)節(jié)
- (void)test3 {
Dog *dog = [[Dog alloc] init];
dog.name = @"旺旺";
dog.identify = @{@"color" : @"red", @"weight" : @"30kg", @"height" : @"60cm"};
[dog serializeValueWithKey:dog.name];
NSLog(@"-----------test3-------------");
Dog *wangwang = [Dog deserializeValueWithKey:@"旺旺"];
NSLog(@"%@", wangwang.identify);
}
總結(jié)
- 單例實(shí)現(xiàn)训桶,便于管理,上層封裝酣倾,代碼簡潔舵揭;
- 實(shí)現(xiàn)簡單,代碼量較性晡午绳;
- 單獨(dú)創(chuàng)建的plist,方便其他頁面打tag映之。
(注:最好不要在項(xiàng)目文件的info.plist中加入非必要的信息) - github用單例模式優(yōu)化本地存儲示例代碼