替换NSUserDefaults的方案

简介:

替换NSUserDefaults的方案

 

效果

 

源码

https://github.com/YouXianMing/iOS-Utilities

//
//  BaseValueStorageManager.h
//  ValueStorageManager
//
//  Created by YouXianMing on 16/3/17.
//  Copyright © 2016年 YouXianMing. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "AbsEncryptingMode.h"

@interface BaseValueStorageManager : NSObject

/**
 *  Config the encryptingMode object and properties prefix, you should run this method first.
 *
 *  @param encryptingMode EncryptingMode object.
 *  @param prefix         Prefix string.
 */
+ (void)configEncryptingMode:(AbsEncryptingMode *)encryptingMode prefix:(NSString *)prefix;

/**
 *  Get the shared instance.
 *
 *  @return Shared instance.
 */
+ (instancetype)sharedInstance;

@end


//
//  BaseValueStorageManager.m
//  ValueStorageManager
//
//  Created by YouXianMing on 16/3/17.
//  Copyright © 2016年 YouXianMing. All rights reserved.
//

#import "BaseValueStorageManager.h"
#import "FastCoder.h"
#import <objc/runtime.h>

static NSMutableDictionary  *_dictionary = nil;

@interface BaseValueStorageManager ()

@property (nonatomic, strong) NSArray            *baseValueStorageManagerProperties;
@property (nonatomic, strong) AbsEncryptingMode  *baseValueStorageManagerEncryptingMode;
@property (nonatomic, strong) NSString           *baseValueStorageManagerPrifixName;

@end

@implementation BaseValueStorageManager

+ (void)initialize {
    
    if (self == [BaseValueStorageManager class]) {
        
        _dictionary = [NSMutableDictionary dictionary];
    }
}

+ (void)configEncryptingMode:(AbsEncryptingMode *)encryptingMode prefix:(NSString *)prefix {
    
    BaseValueStorageManager *newObject              = [[[self class] alloc] init];
    newObject.baseValueStorageManagerEncryptingMode = (encryptingMode == nil ? [AbsEncryptingMode new]         : encryptingMode);
    newObject.baseValueStorageManagerPrifixName     = (prefix         == nil ? NSStringFromClass([self class]) : prefix);
    
    // Get all useful properties.
    NSArray        *allProperties    = [newObject allProperties];
    NSMutableArray *usefulProperties = [NSMutableArray array];
    for (int i = 0; i < allProperties.count; i++) {
        
        NSString *propertyName = allProperties[i];
        if ([propertyName isEqualToString:@"baseValueStorageManagerProperties"] ||
            [propertyName isEqualToString:@"baseValueStorageManagerEncryptingMode"] ||
            [propertyName isEqualToString:@"baseValueStorageManagerPrifixName"]) {
            
            continue;
        }
        
        [usefulProperties addObject:propertyName];
    }
    newObject.baseValueStorageManagerProperties = [NSArray arrayWithArray:usefulProperties];
    
    [_dictionary setObject:newObject forKey:NSStringFromClass([self class])];
    
    // Set all the properties.
    for (int i = 0; i < allProperties.count; i++) {
        
        NSString *key     = allProperties[i];
        NSString *ketPath = [newObject addPrifixWithString:key prifix:newObject.baseValueStorageManagerPrifixName];
        id object         = [[NSUserDefaults standardUserDefaults] objectForKey:ketPath];
        
        if (object) {
            
            object = [FastCoder objectWithData:[newObject.baseValueStorageManagerEncryptingMode decryptData:object]];
            [newObject setValue:object forKey:key];
        }
    }
    
    // KVO
    for (int i = 0; i < newObject.baseValueStorageManagerProperties.count; i++) {
        
        [newObject addObserver:newObject forKeyPath:newObject.baseValueStorageManagerProperties[i]
                       options:NSKeyValueObservingOptionNew context:nil];
    }
}

- (NSString *)addPrifixWithString:(NSString *)string prifix:(NSString *)prefix {
    
    return [NSString stringWithFormat:@"_%@_%@", prefix, string];
}

+ (instancetype)sharedInstance {
    
    return _dictionary[NSStringFromClass([self class])];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    
    BaseValueStorageManager *manager    = object;
    NSString                *newKeyPath = [manager addPrifixWithString:keyPath prifix:_baseValueStorageManagerPrifixName];
    id                       newValue   = [_baseValueStorageManagerEncryptingMode encryptData:[FastCoder dataWithRootObject:change[@"new"]]];
    [[NSUserDefaults standardUserDefaults] setObject:newValue forKey:newKeyPath];
}

/**
 *  Get all properties.
 *
 *  @return Properties array.
 */
- (NSArray *)allProperties {
    
    u_int count;
    objc_property_t *properties      = class_copyPropertyList([self class], &count);
    NSMutableArray  *propertiesArray = [NSMutableArray arrayWithCapacity:count];
    
    for (int i = 0; i<count; i++) {
        
        const char *propertyName = property_getName(properties[i]);
        [propertiesArray addObject:[NSString stringWithUTF8String: propertyName]];
    }
    
    free(properties);
    
    return propertiesArray;
}

- (void)dealloc {
    
    for (int i = 0; i < self.baseValueStorageManagerProperties.count; i++) {
        
        [self removeObserver:self forKeyPath:self.baseValueStorageManagerProperties[i]];
    }
}

@end

细节

目录
相关文章
|
3月前
|
JavaScript 前端开发 API
第9期 一文读懂TS的(.d.ts)文件
第9期 一文读懂TS的(.d.ts)文件
50 0
|
JavaScript 前端开发 API
一文读懂TS的(.d.ts)文件
一文读懂TS的(.d.ts)文件
3840 0
|
8月前
ts的内置工具
ts的内置工具
49 0
|
4月前
ts文件解密
ts文件解密
76 0
|
5月前
|
JavaScript 前端开发 开发者
ts详解以及相关例子(一篇带你详细了解ts)
ts详解以及相关例子(一篇带你详细了解ts)
42 1
|
7月前
|
JavaScript 前端开发
ts - ts基础
https://www.tslang.cn/ TypeScript是Microsoft公司注册商标。 TypeScript具有类型系统,且是JavaScript的超集。 它可以编译成普通的JavaScript代码。 TypeScript支持任意浏览器,任意环境,任意系统并且是开源的。
|
8月前
|
JavaScript 前端开发 IDE
什么是ts,作用是什么
什么是ts,作用是什么
506 0
|
10月前
TS在实际开发中的使用
TS在实际开发中的使用
57 0
ts重点学习131-ts中的命名空间
ts重点学习131-ts中的命名空间
63 0
ts重点学习131-ts中的命名空间

热门文章

最新文章