• 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;
    }
  • 相关阅读:
    SqlSession接口和Executor
    MySQL 存储表情字符
    Lisp学习--Windows下面的开发环境搭建
    使用反射+缓存+委托,实现一个不同对象之间同名同类型属性值的快速拷贝
    GIT团队合作探讨之一-保持工作同步的概念和实践
    关于IE8下media query兼容的解决方案探讨
    git下的团队合作模型及git基础知识汇集
    互联网环境下服务提供的模式
    web统计数据搜集及分析原理
    网站统计及移动应用数据统计相关术语知识详解
  • 原文地址:https://www.cnblogs.com/xinchrome/p/5120249.html
Copyright © 2020-2023  润新知