用單例模式優化本地存儲

1.用單例設計存儲數據接口


1.1單例接口

+ (AppScene *)sharedInstance;

1.2數據序列化接口

- (void)serializeValue:(id)value withKey:(NSString *)key;

1.3數據反序列化接口

- (id)deserializeValueWithKey:(NSString *)key;

2.用單例接口隔離實現細節


2.1替代NSCoding協議

  • 在實現之前先簡單介紹一下fastCoding,因為過程中會用到fastCoding
    fastCoding是用來替代系統的NSCoding的協議 可以將對象序列化成NSData,也可以反序列化成對象。
  • fastCodin在github鏈接或者在github上搜索fastCoding看到star最多的就是。
  • 解壓得到圖中目錄,有用的就只有FastCoder目錄的兩個文件,將這兩個文件加入項目中,編譯會發現有問題。在ARC下會運行的比較slow,可以手動將這個文件改為MRC環境,操作如圖。做完之后,編譯沒有問題了。


    解壓目錄.png
MRC操作.png

2.2數據接口的實現

  • 嚴格單例的實現(在ios最實用的13中設計模式中的單例模式示例代碼中已經詳細說明了,沒有賞光下載觀看的,可以移步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;
    }
}

  • 數據序列化接口的實現
- (void)serializeValue:(id)value withKey:(NSString *)key {
    NSParameterAssert(value);
    NSParameterAssert(key);
    //fastCoding是用來地點系統的NSCoding的協議 
    //可以將對象序列化成NSData,也可以反序列化對象
    NSData *data = [FastCoder dataWithRootObject:value];
    if (data) {
        [[NSUserDefaults standardUserDefaults] setObject:data forKey:key];
    }
}
  • 數據反序列化接口的實現
- (id)deserializeValueWithKey:(NSString *)key {
    NSParameterAssert(key);
    
    NSData *data = [[NSUserDefaults standardUserDefaults] valueForKey:key];
    return [FastCoder objectWithData:data];
}

3.在單例提供接口的基礎上進行上層封裝


3.1編寫NSObject的category(storeValue),如圖所示

category.png

3.2category的實現

- (void)serializeValueWithKey:(NSString *)key {
    
    [[AppScene sharedInstance] serializeValue:self withKey:key];
}

+ (id)deserializeValueWithKey:(NSString *)key {
    
    return [[AppScene sharedInstance] deserializeValueWithKey:key];
}

3.3封裝的優點

隔離所有細節,假設以后更改實現方法,原有代碼無需更改。

4測試


4.1測試結果OK,如圖

測試結果.png

4.2測試代碼,可以感受封裝優點

- (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 = @"旺財";
    dog.identify = @{@"color" : @"black", @"weight" : @"20kg", @"height" : @"50cm"};
    
    [[AppScene sharedInstance] serializeValue:dog withKey:dog.name];
    NSLog(@"-----------test2-------------");
    Dog *wangcai = [[AppScene sharedInstance] deserializeValueWithKey:@"旺財"];
    NSLog(@"%@", wangcai.identify);
}

//test3在test2的基礎上增加了category,在單例提供接口的基礎上進行上層封裝,隔離所有細節
- (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);

}

總結

  1. 單例實現,便于管理,上層封裝,代碼簡潔;
  2. 實現簡單,代碼量較小;
  3. 單獨創建的plist,方便其他頁面打tag。
    (注:最好不要在項目文件的info.plist中加入非必要的信息)
  4. github用單例模式優化本地存儲示例代碼
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,269評論 25 708
  • 單例模式(SingletonPattern)一般被認為是最簡單、最易理解的設計模式,也因為它的簡潔易懂,是項目中最...
    成熱了閱讀 4,292評論 4 34
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,765評論 18 399
  • 晨起感恩 感恩諸佛菩薩三寶加持,感恩歷代祖先護佑,感恩天地滋養萬物,感恩父母養育之恩。 感恩早晨參加仁愛奉粥活...
    夏寧點點閱讀 161評論 0 0
  • 繼續說說三四章吧,精神分析流派,這可是心理學的基石,開山鼻祖。 弗洛伊德很早以前便聽說過,但開始翻閱源于近兩年的學...
    正念此心閱讀 196評論 1 1