数据持久化

IOS文件系统
1.IOS文件系统遵循一个沙盒机制,IOS中的沙盒机制(SandBox)是一种安全体系,它规定了应用程序只能在为该应用创建的文件夹内读取文件,不可以访问其他地方的内容。所有的非代码文件都保存在这个地方,比如图片、声音、属性列表和文本文件等。
1>每个应用程序都在自己的沙盒内
2>不能随意跨越自己的沙盒去访问别的应用程序沙盒的内容
3>应用程序向外请求或接收数据都需要经过权限认证
2.当一个APP被安装在IOS系统,系统就会为其创建一个遵循沙盒机制的文件系统,该文件系统有三个文件:
1>Documents:用户在使用APP过程产生数据都会保存在此文件夹下,如果APP使用了ICloud技术,此文件夹的数据将会进行云同步
2>Library:用户偏好设置及缓存设置,通常和NSUserDefualt类来访问此文件路径
3>tmp
3.系统提供两个类来操作APP的文件系统
NSFileManager NSFileHandle
沙盒路径目录结构
Documents:应用程序将其数据存储在Documents目录中,例如从网路下载的图片或者应用程序产生的文档内容等
目录路径的获取:

NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
  NSLog(@"%@", path);

注:第一个参数为查找的是Documents目录,第二个参数指定的是讲搜索限制在应用程序沙盒内,第三个参数如果为yes会将检索后的路径中~符号展开为实际路径,由于检索处的paths为一个数组,但是里面只有一个路径,所以用firstObject来获取唯一的Documents路径。

Library:用户首选项设置都存储在Library/Preferences文件夹中。该文件夹一般不作为应用程序产生文档的存储位置。
目录路径的获取:

NSString *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
  NSLog(@"%@", path);

tmp:该目录提供应用程序存储临时文件,应用程序中产生的文档页可以临时放入此目录,但是此目录在iTunes同步设备时不备份。
目录路径的获取:

NSString *path = NSTemporaryDirectory();
  NSLog(@"%@", path);

数据持久化分大概分为以下5种

plist文件(属性列表)
preference(偏好设置)
NSKeyedArchiver(归档)
SQLite 3

CoreData
一、plist文件(属性列表)
plist文件是将某些特定的类,通过XML文件的方式保存在目录中。 用于存储键值对小数据是最合算的,因为其速率快!
//路径的获取

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath = [paths objectAtIndex:0];
     NSString *myFile = [docPath stringByAppendingPathComponent:@"my.list”];
 //写入文件 存储时使用writeToFile: atomically:方法。 其中atomically表示是否需要先写入一个辅助文件,再把辅助文件拷贝到目标文件地址。这是更安全的写入文件方法,一般都写YES。
     NSArray *array = @[@"123", @"456", @"789"];
     [array writeToFile:myFile atomically:YES];
//文件读取
   NSArray *result = [[NSArray alloc] initWithContentsOfFile:myFile];

二、preference(偏好设置)
//1.获得NSUserDefaults文件
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
//2.向文件中写入内容
[userDefaults setObject:@"AAA" forKey:@"a"];
[userDefaults setBool:YES forKey:@"sex"];
[userDefaults setInteger:21 forKey:@"age"];
//2.1立即同步
[userDefaults synchronize];
//3.读取文件
NSString *name = [userDefaults objectForKey:@"a"];
BOOL sex = [userDefaults boolForKey:@"sex"];
NSInteger age = [userDefaults integerForKey:@"age"];
NSLog(@"%@, %d, %ld", name, sex, age);

注:
1.偏好设置是专门用来保存应用程序的配置信息的,一般不要在偏好设置中保存其他数据。
2.如果没有调用synchronize方法,系统会根据I/O情况不定时刻地保存到文件中。所以如果需要立即写入文件的就必须调用synchronize方法。
3.偏好设置会将所有数据保存到同一个文件中。即preference目录下的一个以此应用包名来命名的plist文件。

三、NSKeyedArchiver(归档)

如果要归档的类型为标量或者是已经实现了NSCoding协议的,均不需要再进行特殊处理,可直接进行归档。如果是自定义类型,则必须要实现NSCoding协议才可以进行归档操作。
NSCoding协议声明了两个方法,这两个方法都是必须实现的。一个用来说明如何将对象编码到归档中,另一个说明如何进行解档来获取一个新对象(取消归档)。两个方法都传递一个NSCoder实例的参数。使用这个参数可以对这些自定义对象的各个成员进行编码和解码。如果自定义对象的成员中包含了另外的自定义对象,这个被包含的自定义对象也要实现NSCoding协议。

实现如下

新建一个类,并遵循NSCoding协议
//归档
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_desc forKey:@”desc”];
[aCoder encodeObject:_imageurls forKey:@”imageurls”];
[aCoder encodeObject:_source forKey:@”source”];
[aCoder encodeObject:_title forKey:@”title”];
[aCoder encodeObject:_link forKey:@”link”];
}
注:如果需要归档的类是某个自定义类的子类时,就需要在归档和解档之前先实现父类的归档和解档方法。即 [super encodeWithCoder:aCoder] 和 [super initWithCoder:aDecoder] 方法;
//解档
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
[aDecoder decodeObjectForKey:@”desc”];
[aDecoder decodeObjectForKey:@”imageurls”];
[aDecoder decodeObjectForKey:@”source”];
[aDecoder decodeObjectForKey:@”title”];
[aDecoder decodeObjectForKey:@”link”];
}
return self;
}

到需要值得视图控制器进行写入和读取

//读取归档文件
NSData *data = [[NSMutableDataalloc] initWithContentsOfFile:myFile];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiveralloc] initForReadingWithData:data];
TestObj * test = [unarchiver decodeObjectForKey:@”data”];
[unarchiver finishDecoding];
//写入归档文件
NSMutableData *data1 = [[NSMutableDataalloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiveralloc] initForWritingWithMutableData:data1];
[archiver encodeObject:test forKey:@”data”];
[archiver finishEncoding];
[data writeToFile:myFile atomically:YES];

四、文件的写入和读取

1.写入 //应用程序根目录的获取

NSString *homePath = NSHomeDirectory();

NSLog(@”%@”,homePath);
//Documents目录的获取
// NSString *documentPath = [homePath stringByAppendingPathComponent:@”documents”];

NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
//创建一个文件夹

NSFileManager *fileManager = [NSFileManager defaultManager];
//首先判断是否存在此文件夹
NSString *dirPath = [documentPath stringByAppendingPathComponent:@”diary”];
if(![fileManagerfileExistsAtPath:dirPath]) {[fileManagercreateDirectoryAtPath:dirPathwithIntermediateDirectories:YESattributes:nilerror:nil];
}
//将需要的数据保存到字典中
NSDictionary*dic =@{@”content”:self.textView.text,@”date”:[NSDatedate]};
//时间格式转换
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:@”yyyy年MM月dd日HH时mm分ss秒”];
NSString *string = [dateFormatter stringFromDate:[NSDate date]];
//将时间保存为文件名称后缀为txt
NSString *filePath = [dirPath stringByAppendingPathComponent:[NSString stringWithFormat:@”%@.txt”,string]];
//判断是否写入成功
if ([dic writeToFile:filePath atomically:YES]) {
self.textView.text = @”“;
}else{
NSLog(@”保存失败”);
}

2.读取
//读文件
//拿数据
NSString*documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)firstObject];

NSString *dirPath = [documentPath stringByAppendingPathComponent:@”diary”];

//将去到数据放到数组
dataSource = [NSMutableArray arrayWithArray:[[NSFileManager defaultManager] subpathsAtPath:dirPath]];

四、coredata的使用
在已有文件创建coredata时需要以下配置
在app delegate.m文件中添加

#pragma mark - Core Data stack
@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;

- (NSURL *)applicationDocumentsDirectory {
  // The directory the application uses to store the Core Data store file. This code uses a directory named "com.Yujunliu.UI__coreData" in the application's documents directory.
  return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
- (NSManagedObjectModel *)managedObjectModel {
  // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
  if (_managedObjectModel != nil) {
      return _managedObjectModel;
    }
  NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"GifModel" withExtension:@"momd"];
  _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
  return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
  // The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it.
  if (_persistentStoreCoordinator != nil) {
      return _persistentStoreCoordinator;
    }

  // Create the coordinator and store
  _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
  NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"GifModel.sqlite"];
  NSError *error = nil;
  NSString *failureReason = @"There was an error creating or loading the application's saved data.";
  if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
      // Report any error we got.
      NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data";
        dict[NSLocalizedFailureReasonErrorKey] = failureReason;
        dict[NSUnderlyingErrorKey] = error;
        error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
      // Replace this with code to handle the error appropriately.
      // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
      abort();
    }
  return _persistentStoreCoordinator;
}
- (NSManagedObjectContext *)managedObjectContext {
  // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
  if (_managedObjectContext != nil) {
      return _managedObjectContext;
    }
  NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
  if (!coordinator) {
      return nil;
    }
  _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
  return _managedObjectContext;
}

#pragma mark - Core Data Saving support

- (void)saveContext {
  NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
  if (managedObjectContext != nil) {
      NSError *error = nil;
      if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
          // Replace this implementation with code to handle the error appropriately.
          // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
          NSLog(@"Unresolved error %@, %@", error, [error userInfo]);

          abort();
        }
    }
}
在app delegate.h文件中添加

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;

- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;
//插入数据
+(BOOL)insertGifModel:(NSDictionary*)gifmodelDic{
  BOOL flag = NO;

  //拿到context
  AppDelegate *appdelegate = [UIApplication sharedApplication].delegate;
  NSManagedObjectContext *context = appdelegate.managedObjectContext;
  GifModel *gifModel = [NSEntityDescription insertNewObjectForEntityForName:@"GifModel" inManagedObjectContext:context];


  //进行赋值插入
    gifModel.headpicture = gifmodelDic[@"headpicture"];
    gifModel.nickname = gifmodelDic[@"nickname"];
    gifModel.createtime = gifmodelDic[@"createtime"];
    gifModel.text = gifmodelDic[@"text"];
    gifModel.commentsno = gifmodelDic[@"commentsno"];
    gifModel.gifurl = gifmodelDic[@"gifurl"];
  gifModel.isZan = gifmodelDic[@"isZan"];
    gifModel.newsid = gifmodelDic[@"newsid"];
    gifMdel.userid = gifmodelDic[@"userid"];

  //保存
    [appdelegate saveContext];
  NSError *error = nil;
  if ([context save:&error]) {
      NSLog(@"插入成功");
        flag = YES;
    }else{
      NSLog(@"error = %@",error.debugDescription);
    }
  return flag;
}
//根据条件修改数据
+(BOOL)updataGifModel:(NSFetchRequest *)fetchRequst string:(NSString *)newContent{
  BOOL flag = NO;

  //拿到context
  AppDelegate *appdelegate = [UIApplication sharedApplication].delegate;
  NSManagedObjectContext *context = appdelegate.managedObjectContext;
  NSError *error = nil;
  NSArray *datas = [context executeFetchRequest:fetchRequst error:&error];
  if (!error && datas.count >0) {
      for (int i = 0; i<datas.count; i++) {
          //赋值新值
          GifModel *gifModel = datas[i];
            gifModel.text = newContent;
            [appdelegate saveContext];
          if ([context save:&error]) {
              NSLog(@"修改成功");
                flag = YES;
            }else{
              NSLog(@"修改失败");
                flag = NO;
            }
        }
    }
  return flag;
}
//根据条件删除数据
+(BOOL)deleteGifModel:(NSFetchRequest *)fetchRequest{
  BOOL flag = NO;
  //拿到context
  AppDelegate *appdelegate = [UIApplication sharedApplication].delegate;
  NSManagedObjectContext *context = appdelegate.managedObjectContext;
  NSError *error = nil;
  NSArray *datas = [context executeFetchRequest:fetchRequest error:&error];
  if (!error && datas.count>0) {
      for (int i =0; i<datas.count; i++) {
          //删除满足条件的gifModel
            [context deleteObject:datas[i]];
            [appdelegate saveContext];
          if ([context save:&error]) {
              NSLog(@"删除成功");
                flag = YES;
            }else{
              NSLog(@"error = %@",error.debugDescription);
                flag = NO;
            }
        }
    }
  return flag;
}
//删除所有数据
+(BOOL)deleteAll{
  BOOL flag = NO;
  //拿到context
  AppDelegate *appdelegate = [UIApplication sharedApplication].delegate;
  NSManagedObjectContext *context = appdelegate.managedObjectContext;
  NSEntityDescription *description = [NSEntityDescription entityForName:@"GifModel" inManagedObjectContext:context];
  NSFetchRequest *request = [[NSFetchRequest alloc]init];
    [request setIncludesPropertyValues:NO];
    [request setEntity:description];
    flag = [GifModel deleteGifModel:request];
  return flag;
}
//查找所有数据
+(NSMutableArray *)find{
  NSMutableArray *array = [NSMutableArray array];
  //拿到context
  AppDelegate *appdelegate = [UIApplication sharedApplication].delegate;
  NSManagedObjectContext *context = appdelegate.managedObjectContext;
  NSEntityDescription *description = [NSEntityDescription entityForName:@"GifModel" inManagedObjectContext:context];
  NSFetchRequest *request = [[NSFetchRequest alloc]init];
    [request setIncludesPropertyValues:NO];
    [request setEntity:description];
  NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"newsid" ascending:NO];
    request.sortDescriptors = @[sort];
  NSError *error = nil;
  NSArray *datas = [context executeFetchRequest:request error:&error];
  if (!error) {
        [array addObjectsFromArray:datas];
    }
  NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
  NSLog(@"%@",path);
  return array;
}
//根据条件查询数据
+(NSMutableArray *)findWithFetchRequest:(NSFetchRequest *)request{
  NSMutableArray *array = [NSMutableArray array];
  //拿到context
  AppDelegate *appdelegate = [UIApplication sharedApplication].delegate;
  NSManagedObjectContext *context = appdelegate.managedObjectContext;
  NSError *error = nil;
  NSArray *datas = [context executeFetchRequest:request error:&error];
  if (!error) {
        [array addObjectsFromArray:datas];
    }
  return array;
}

coredata的增删改查方法就这样定义完了,当需要进行数据库操作时,调用方法即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值