替换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
细节
时间: 2024-11-29 03:39:10