Cocoa Touch(二):数据存储CoreData, NSKeyArchiver, NSOutputStream, NSUserDefaults

应用程序离不开数据的永久存储,有两种方式实现存储:数据库和文本文件。

作为存储管理器,最基本的功能就是增删改查了。

CoreData

1、插入

AppDelegate *app = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [app managedObjectContext];
NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"entityname" inManagedObjectContext:context];
[newManagedObject setValue:value forKey:@"propertyname"];
NSError *error; 
if (![context save:&error]) {

    // Handle the error…
}

2、查询

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext;
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Hero" inManagedObjectContext:managedObjectContext];
NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc]initWithKey:@”name” ascending:YES];
NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc]initWithKey:@”secretIdentity” ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc]initWithObjects:sortDescriptor1, sortDescriptor2, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
NSArray *objecs = [context executeFetchRequest: fetchRequest error:&error];
if(objets==nil || error != nil){
  //做处理 }

3、修改

-(void)applicationWillResignActive:(NSNotification *)notification{
    NSLog(@"applicationWillResignActive");
    //创建托管对象上下文
    NSManagedObjectContext *context = [appDelegate managedObjectContext];
    NSFetchRequest *request = [[NSFetchRequest alloc]init];
    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"User" inManagedObjectContext:context];
    [request setEntity:entityDescription];
    
    NSManagedObject *user = nil;
    NSError *error;
    NSArray *objets = [context executeFetchRequest:request error:&error];
    if(objets==nil){
        NSLog(@"There has a error!");
        //做错误处理
    } 
    if([objets count]>0){
        //非第一次,更新数据
        NSLog(@"更新操作");
        user = [objets objectAtIndex:0];
    }else{
        NSLog(@"插入操作");
        //第一次保存,插入新数据
        user = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:context];
    }  
    [user setValue:self.serverIp.text forKeyPath:@"serverIp"];
    [user setValue:self.userName.text forKeyPath:@"userName"];
    [context save:&error];
}

4、删除

NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext;
[context deleteObject:[objecs objectIndex:index];
NSError *error; 
if (![context save:&error]) {
    NSLog(@”Unresolved error %@, %@”, error, [error userInfo]);
    exit(-1); // Fail
}

 5、数据迁移

当程序变化时,在很多简单的情况下,Coredata提供了轻量级的自动数据迁移,比如以下三个情况可以通过开启CoreData自动迁移实现:
1.简单的增加一个字段
2.把一个必填字段改为可选字段
3.把可选字段改为必填字段(但一定要定义默认值)

文本读写

  文本是存储在外存上的字节序列,进程需要在内存中创建缓冲区(通常称之为“流”或“stream”,NSData和NSOutputStream的实例都对应“流”的概念),然后再进行读写,不过NSData一般配合NSArchiver一起使用来存储对象,对于文本读写、网络传输,一般用NSOutputStream来作为缓冲区,一个缓冲区对象封装一些读写方法告诉线程如何进行读写。

  在下面的例子中,进程调用inputData将学生数据插入对象关系数据库,在调用queryStudents读取学生信息,暂存在输出流NSOutputStream的实例中,然后写入CSV文本文件。

- (void)createFile:(NSString *)fileName;
- (void)exportCSV:(NSString *)fileName;
- (NSArray *)queryStudents;

//控件关联方法
- (IBAction)inputData:(id)sender {
    
    AppDelegate *app = [[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *context = app.managedObjectContext;
     
    Student *stu = (Student *)[NSEntityDescription insertNewObjectForEntityForName:@"Student" inManagedObjectContext:context];
    stu.name = self.nameTextField.text;
    stu.num = self.numTextField.text;   
    
    NSError *error = nil;
    [context save:&error];   
    
    self.nameTextField.text = @"";
    self.numTextField.text = @"";
}

- (IBAction)makeCSV:(id)sender {
    
    NSArray *documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDirectory, YES);
    NSString *docementDir = [documents objectAtIndex:0];
    NSString *filePath = [docementDir stringByAppendingPathComponent:@"student.csv"];
    NSLog(@"filePath = %@", filePath);    
    
    [self createFile:filePath];
    [self exportCSV:filePath];
}


//私有方法
- (void)createFile:(NSString *)fileName {
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager removeItemAtPath:fileName error:nil];  
    if (![fileManager createFileAtPath:fileName contents:nil attributes:nil]) {
        NSLog(@"不能创建文件");
    }
     
}

- (void)exportCSV:(NSString *)fileName {
    
    
    NSOutputStream *output = [[NSOutputStream alloc] initToFileAtPath:fileName append:YES];
    [output open];
    
    
    if (![output hasSpaceAvailable]) {
        NSLog(@"没有足够可用空间");
    } else {        
        NSString *header = @"学好,姓名
";
        const uint8_t *headerString = (const uint8_t *)[header cStringUsingEncoding:NSUTF8StringEncoding];
        NSInteger headerLength = [header lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
        NSInteger result = [output write:headerString maxLength:headerLength];
        if (result <= 0) {
            NSLog(@"写入错误");
        }       
        
        NSArray *students = [self queryStudents];
        for (Student *stu in students) {         
            NSString *row = [NSString stringWithFormat:@"%@,%@
", stu.num, stu.name];
            const uint8_t *rowString = (const uint8_t *)[row cStringUsingEncoding:NSUTF8StringEncoding];
            NSInteger rowLength = [row lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
            result = [output write:rowString maxLength:rowLength];
            if (result <= 0) {
                NSLog(@"无法写入内容");
            }           
        }
    }
    [output close];
}

- (NSArray *)queryStudents {
    
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:self.managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    fetchRequest.entity = entity;
    NSArray *students = [self.managedObjectContext executeFetchRequest:fetchRequest error:nil];    
    return students;
}
原文地址:https://www.cnblogs.com/xinchrome/p/5120249.html