2019-04-13 11:00:14 正式开始写简书,为了记录自己的学习经历,同时也分享自己的学习成果。当然有不对的地方非常欢迎大家提出,这样既能提高自己,也能防止误导别人╮( ̄▽ ̄)╭
OK,进入正题:
1.UserDefualt
最简单的数据存储方式了,直接上代码
//UserDefualt
NSMutableArray *mutArr = [[NSMutableArray alloc] initWithObjects:@"1", @"2", nil];
NSArray *arr = [NSArray array];
//1.UserDefualt存储数据
[[NSUserDefaults standardUserDefaults] setObject:mutArr forKey:@"myData"];
arr = [[NSUserDefaults standardUserDefaults] valueForKey:@"myData"];
NSLog(@"arr = %@ \n", arr);
[mutArr addObject:@"3"];
[[NSUserDefaults standardUserDefaults] setObject:mutArr forKey:@"myData"];
arr = [[NSUserDefaults standardUserDefaults] valueForKey:@"myData"];
NSLog(@"arr = %@ \n", arr);
2.操作plist文件
对plist文件操作:需要获取文件存储路径后创建.plist文件,之后用系统提供的NSFileManager对文件进行操作,文件可以存在系统沙盒目录下的Document或者Cache文件,这里选择Document。
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"testLocalStorageData.plist"];
NSLog(@"path = %@ \n", path);
NSFileManager *fm = [NSFileManager defaultManager];
[fm createFileAtPath:path contents:nil attributes:nil];
//写入
NSDictionary *dic = @{@"value1":@"key1", @"value2":@"key2"};
[dic writeToFile:path atomically:YES];
//读出
NSDictionary *dicc = [NSDictionary dictionaryWithContentsOfFile:path];
NSLog(@"dicc = %@ \n", dicc);
3.解归档
解归档能够存储对象数据,需要实现<NSCoding>或者<NSSecureCoding>协议,后者有一定加密措施。
.h文件
@interface TestClass : NSObject <NSSecureCoding> //解归档遵守NSCoding协议
.m文件
#pragma mark -NSSecureCoding方法实现
- (void)encodeWithCoder:(nonnull NSCoder *)aCoder {
[aCoder encodeObject:self.test1 forKey:@"test1"];
[aCoder encodeObject:self.test2 forKey:@"test2"];
[aCoder encodeObject:self.test3 forKey:@"test3"];
}
- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder {
if (self == [super init]) {
self.test1 = [aDecoder decodeObjectForKey:@"test1"];
self.test2 = [aDecoder decodeObjectForKey:@"test2"];
self.test3 = [aDecoder decodeObjectForKey:@"test3"];
}
return self;
}
//加密协议需要实现下面的方法
+ (BOOL)supportsSecureCoding {
return YES;
}
使用:
TestClass *myclass = [TestClass new];
myclass.test1 = @"123";
myclass.test2 = @"456";
myclass.test3 = @"789";
NSLog(@"myclass = %@", myclass.test1);
NSString *archPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
NSString *archFilePath = [archPath stringByAppendingPathComponent:@"archData.data"];
NSLog(@"----------%@", NSStringFromClass(myclass.class));
NSError *error;
//iOS12.0弃用
//[NSKeyedArchiver archiveRootObject:myclass toFile:archFilePath];
//归档
NSData *archData = [NSKeyedArchiver archivedDataWithRootObject:myclass requiringSecureCoding:YES error:&error];
NSLog(@"archData = %@", archData);
if (error) {
NSLog(@"archError : %@", error);
}else{
[archData writeToFile:archFilePath atomically:YES];
}
//解档
NSData *unarch = [[NSData alloc] initWithContentsOfFile:archFilePath];
TestClass *content = [NSKeyedUnarchiver unarchivedObjectOfClass:NSClassFromString(@"TestClass") fromData:unarch error:&error];
if (error){
NSLog(@"unarchError->%@", error);
}else{
NSLog(@"content = %@", content.test1);
}
4.CoreData
用来存储数据形态更复杂的数据,首先创建.xcdatamodeld文件,具体步骤:NewFile->DataModel->名字->创建。 CoreData.png封装CoreData方法为JCCoreDataManager
#import "JCCoreDataManager.h"
#define JC_CHECK_NSSTRING(str) ((str == nil) || ([str isEqualToString: @""]) || (str == NULL) || ([str isKindOfClass:[NSNull class]]))
@interface JCCoreDataManager(){
NSString *path;
NSString *dbFolderPath;
NSError *error;
}
/**
数据模型
*/
@property (nonatomic, strong) NSManagedObjectModel *objectModel;
/**
管理数据的对象
*/
@property (nonatomic, strong) NSManagedObjectContext *objectContext;
/**
持久化数据
*/
@property (nonatomic, strong) NSPersistentStoreCoordinator *coordinator;
@end
@implementation JCCoreDataManager
static JCCoreDataManager *manager = nil;
#pragma mark - 单例
+ (instancetype)sharedInstanceManager{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[JCCoreDataManager alloc] init];
});
return manager;
}
- (instancetype)init
{
self = [super init];
if (self) {
//文件路径
path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
dbFolderPath = [path stringByAppendingPathComponent:@"CoreData"];
NSError *error;
//创建托管对象模型
NSURL *url = [[NSBundle mainBundle] URLForResource:@"TestModel" withExtension:@"momd"];
_objectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:url];
//创建持久化协调器
_coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:_objectModel];
//创建本地数据库文件
[_coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self dbPath] options:nil error:&error];
//创建托管对象上下文
_objectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_objectContext setPersistentStoreCoordinator:_coordinator];
}
return self;
}
/**
获取数据库路径
@return NSURL
*/
- (NSURL *)dbPath {
NSError *error = nil;
if (![self checkPathExist]) {
[[NSFileManager defaultManager] createDirectoryAtPath:dbFolderPath withIntermediateDirectories:YES attributes:nil error:&error];
}
if (error){
NSLog(@"创建CoreManager文件失败,error---->%@ \n", error);
return nil;
}
NSURL *dbUrl = [[NSURL fileURLWithPath:dbFolderPath] URLByAppendingPathComponent:@"myDB.sqlite"];
return dbUrl;
}
-(BOOL) checkPathExist{
return [[NSFileManager defaultManager] fileExistsAtPath:dbFolderPath];
}
#pragma mark - 删除数据库
+ (NSString *)deleteCoreData{
NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *fileFolderPath = [documentPath stringByAppendingPathComponent:@"CoreData"];
NSError *error;
if ([[NSFileManager defaultManager] fileExistsAtPath:fileFolderPath]){
[[NSFileManager defaultManager] removeItemAtPath:fileFolderPath error:&error];
}else{
return @"没有数据,请先创建";
}
if (error){
return [NSString stringWithFormat:@"删除失败,error--->%@", error];
}
return @"删除成功";
}
//=============数据库操作===============//
#pragma mark -获取数据模型
+ (NSManagedObject *)getManagedObjectWithEntityName:(NSString *)entityName{
NSManagedObject *managedObject = [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:[JCCoreDataManager sharedInstanceManager].objectContext];
return managedObject;
}
#pragma mark -存储数据
+ (NSString *)save{
JCCoreDataManager *manager = [JCCoreDataManager sharedInstanceManager];
if (![manager checkPathExist]) {
//manager = [[JCCoreDataManager alloc] init];
[manager.coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[manager dbPath] options:nil error:nil];
}
NSError *saveError = nil;
if ([manager.objectContext save:&saveError]) {
return @"存储成功";
}else{
return [NSString stringWithFormat:@"存储失败,error->%@", saveError];
};
}
#pragma mark -更新数据
+ (BOOL)updateManagedObject:(NSManagedObject *)managedObject{
[[JCCoreDataManager sharedInstanceManager].objectContext refreshObject:managedObject mergeChanges:YES];
return [JCCoreDataManager save];
}
#pragma mark -查找数据
+ (NSArray *)searchCoreDataWithEntityName:(NSString *)entityName andAttribute:(NSString *)attribute andSelectName:(NSString *)searchName sorting:(NSString *)sortAttribute isAsending:(BOOL)isAsending{
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:[JCCoreDataManager sharedInstanceManager].objectContext];
//创建fetch请求
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
fetchRequest.entity = entity;
//一次获取全部数据
[fetchRequest setFetchBatchSize:0];
NSSortDescriptor *nameDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
NSSortDescriptor *ageDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES];
NSSortDescriptor *bloodTypeDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"bloodType" ascending:YES];
if (JC_CHECK_NSSTRING(sortAttribute) || ([sortAttribute isEqualToString:@"name"])) {
// NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:sortAttribute ascending:isAsending];
fetchRequest.sortDescriptors = @[nameDescriptor, ageDescriptor, bloodTypeDescriptor];
}else if ([sortAttribute isEqualToString:@"age"]){
fetchRequest.sortDescriptors = @[ageDescriptor, nameDescriptor, bloodTypeDescriptor];
}else{
fetchRequest.sortDescriptors = @[bloodTypeDescriptor, nameDescriptor, ageDescriptor];
}
if (!JC_CHECK_NSSTRING(attribute) && !JC_CHECK_NSSTRING(searchName)) {
//查找某个属性的值包含某个字符串
//%K 属性的值 %@ 字符串 ==
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"%K CONTAINS[cd] %@", attribute, searchName];
}
NSFetchedResultsController *fetchController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[JCCoreDataManager sharedInstanceManager].objectContext sectionNameKeyPath:nil cacheName:nil];
NSError *error;
if ([fetchController performFetch:&error]){
return [fetchController fetchedObjects];
}else{
NSLog(@"%@", error);
return @[];
}
}
#pragma mark -删除数据
+ (NSString *)deleteWithEntityName:(NSString *)entityName andAttribute:(NSString *)attribute andSearchName:(NSString *)searchName{
//没有删除条件
if (JC_CHECK_NSSTRING(attribute) || JC_CHECK_NSSTRING(searchName)) {
return @"没有删除条件或条件不完整";
}
//查找
NSArray *arr = [JCCoreDataManager searchCoreDataWithEntityName:entityName andAttribute:attribute andSelectName:searchName sorting:attribute isAsending:YES];
if (arr.count == 0)
return @"没有找到数据";
if (arr.count>0) {
//删除
for (NSManagedObject *object in arr) {
[[JCCoreDataManager sharedInstanceManager].objectContext deleteObject:object];
}
}
//存储数据
[JCCoreDataManager save];
return @"删除成功";
}
@end
数据处理和创建都只针对JCStudentModel,后面会补充相关数据的创建、关联、查找、删除。
创建数据(10个随机数据为例)
for (int i = 0; i<10; i++) {
JCStudentModel *studentModel = (JCStudentModel *)[JCCoreDataManager getManagedObjectWithEntityName:NSStringFromClass([JCStudentModel class])];
uint32_t r = arc4random_uniform(99)+1;
studentModel.name = [NSString stringWithFormat:@"student%@", r<10?[NSString stringWithFormat:@"0%u", r]:[NSString stringWithFormat:@"%u", r]];
studentModel.age = arc4random_uniform(8)+10;
studentModel.bloodType = arc4random_uniform(101)>50?@"A":@"B";
}
NSString *ans = [JCCoreDataManager save];
其他都只要调用一句即可:
//删除所有数据
[JCCoreDataManager deleteCoreData];
//条件查找
NSArray *a = [JCCoreDataManager searchCoreDataWithEntityName:NSStringFromClass([JCStudentModel class]) andAttribute:attribute andSelectName:selectName sorting:sortAttribute isAsending:YES];
//条件删除
[JCCoreDataManager deleteWithEntityName:NSStringFromClass([JCStudentModel class]) andAttribute:attribute andSearchName:_keyWordsTextField.text];
网友评论