zoukankan      html  css  js  c++  java
  • 存储问题

    1.本地储存数据有哪些方式?

    答:NSKeyedArchiver(加密形式)、NSUserDefaults、Write(写入形式)、SQLite3

    2.什么是序列化和反序列化,可以用来做什么?如何在OC中实现复杂对象的存储?

    答:(1)把对象转换为字节序列的过程称为对象的序列化

    (2)把字节序列恢复为对象的过程称为对象的反序列化

    将对象写到文件或者数据库里,并且可以读取出来 遵循NSCoding协议,来实现复杂对象的存储 实现该协议后就可以对其进行打包或者解包,然后转化为NSData

    3.SQLite数据存储是怎么用?

    答:先添加SQLite动态库(libsqlite3.dylib),然后导入头文件(#import <sqlite3.h>),最后用C语言函数去创建/打开数据库,进行SQL语句编写。

    4.简述客户端的缓存机制?

    答:首先缓冲可分为:内存数据缓存、数据库缓存、文件缓存

    当我们获取数据的时候,首先检测内存有没有缓存,再检测本地缓存,最后发送网络请求,将服务器返回的网络进行请求,以便以下次还直接读取。

    5.你实现过多线程的Core Data吗?NSPersistenStoreCoordinator,NSManagedObjectContexit和NSManagedObject中的那些需要在线程中创建或者传递?你是用什么样的策略来实现的呢?

    答:CoreData是对SQLite数据库的封装,而它在NSManageredObject在多线程中不安全,如果要使用它的多线程的话就用:NSManagedObjectContext。

    因为NSManagedObjectContext对象可以使用同一个NSPerdidtenStoreCoordinator实例,之所以可以,是因为MSMangedObjectContext之前把它上锁了。

    这是对以上的只是扩展:

    FMDB:OC封装C语言的SQLite,编写SQL语句

          CoreData:OC封装C语言的SQLite,不用编写任何SQL语句

    6.本地数存储方式的拓展(主要用来参考)

     在iOS开发过程中,不管是做什么应用,都会碰到数据保存的问题。将数据保存到本地,能够让程序的运行更加流畅,不会出现让人厌恶的菊花形状,使得用户体验更好。下面介绍一下数据保存的方式:

      1.NSKeyedArchiver:采用归档的形式来保存数据,该数据对象需要遵守NSCoding协议,并且该对象对应的类必须提供encodeWithCoder:和initWithCoder:方法。前一个方法告诉系统怎么对对象进行编码,而后一个方法则是告诉系统怎么对对象进行解码。例如对Possession对象归档保存。

      定义Possession:

      @interface Possession:NSObject<NSCoding>{//遵守NSCoding协议

             NSString *name;//待归档类型

      }

      @implementation Possession

      -(void)encodeWithCoder:(NSCoder *)aCoder{

                  [aCoder encodeObject:name forKey:@"name"];

      }

      -(void)initWithCoder:(NSCoder *)aDecoder{

                  name=[[aDeCoder decodeObjectforKey:@"name"] retain];

      }

      归档操作:

      如果对Possession对象allPossession归档保存,只需要NSCoder子类NSKeyedArchiver的方法archiveRootObject:toFile: 即可。

      NSString *path = [self possessionArchivePath];

      [NSKeyedArchiver archiveRootObject:allPossessions toFile: path ]

      解压操作:

      同样调用NSCoder子类NSKeyedArchiver的方法unarchiveRootObject:toFile: 即可  

      allPossessions = [[NSKeyedUnarchiver unarchiveObjectWithFile:path] retain];

    缺点:归档的形式来保存数据,只能一次性归档保存以及一次性解压。所以只能针对小量数据,而且对数据操作比较笨拙,即如果想改动数据的某一小部分,还是需要解压整个数据或者归档整个数据。

      2.NSUserDefaults:用来保存应用程序设置和属性、用户保存的数据。用户再次打开程序或开机后这些数据仍然存在。NSUserDefaults可以存储的数据类型包括:NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary。如果要存储其他类型,则需要转换为前面的类型,才能用NSUserDefaults存储。具体实现为:

      保存数据:

      NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];
    NSString *name =@”default string“;
    [defaults setObject:firstName forKey:@"name"];
      //获得UIImage实例

     UIImage *image=[[UIImage alloc]initWithContentsOfFile:@"photo.jpg"];

     NSData *imageData = UIImageJPEGRepresentation(image, 100);//UIImage对象转换成NSData

     [defaults synchronize];//用synchronize方法把数据持久化到standardUserDefaults数据库

      读取数据

      NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];
    NSString *name = [defaults objectForKey:@"name"];//根据键值取出name
    NSData *imageData = [defaults dataForKey:@"image"];
    UIImage *Image = [UIImage imageWithData:imageData];//NSData转换为UIImage

      3. Write写入方式:永久保存在磁盘中。具体方法为:

      第一步:获得文件即将保存的路径:

      NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,  NSUserDomainMask,YES);//使用C函数NSSearchPathForDirectoriesInDomains来获得沙盒中目录的全路径。该函数有三个参数,目录类型、he domain mask、布尔值。其中布尔值表示是否需要通过~扩展路径。而且第一个参数是不变的,即为NSSearchPathDirectory 。在IOS中后两个参数也是不变的,即为:NSUserDomainMask 和 YES。
     NSString *ourDocumentPath =[documentPaths objectAtIndex:0];

    还有一种方法是使用NSHomeDirectory函数获得sandbox的路径。具体的用法为:

    NSString *sandboxPath = NSHomeDirectory();
    // Once you have the full sandbox path, you can create a path from it,但是不能在sandbox的本文件层上写文件也不能创建目录,而应该是此基础上创建一个新的可写的目录,例如Documents,Library或者temp。
    NSString *documentPath = [sandboxPath
                stringByAppendingPathComponent:@"Documents"];//将Documents添加到sandbox路径上,具体原因前面分析了!

      这两者的区别就是:使用NSSearchPathForDirectoriesInDomains比在NSHomeDirectory后面添加Document更加安全。因为该文件目录可能在未来发送的系统上发生改变。

      第二步:生成在该路径下的文件:

      NSString *FileName=[documentDirectory stringByAppendingPathComponent:fileName];//fileName就是保存文件的文件名

    第三步:往文件中写入数据:

      [data writeToFile:FileName atomically:YES];//将NSData类型对象data写入文件,文件名为FileName

      最后:从文件中读出数据:

      NSData data=[NSData dataWithContentsOfFile:FileName options:0 error:NULL];//从FileName中读取出数据
    4. SQLite:采用SQLite数据库来存储数据。SQLite作为一中小型数据库,应用ios中,跟前三种保存方式相比,相对比较复杂一些。还是一步步来吧!

      第一步:需要添加SQLite相关的库以及头文件:在项目文件的Build Phases下,找到Link Binary Library(ies),添加libsqlite3.0.dylib(libsqlite3.dylib与前者的区别暂时不知,两者应该差不多);在项目文件中头文件或者源文件中添加头文件#import "/usr/include/sqlite3.h"

      第二步:开始使用SQLite:

      NSArray *documentsPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask , YES);
    NSString *databaseFilePath=[[documentsPaths objectAtIndex:0] stringByAppendingPathComponent:@"mydb"];
    //上面两句已经比较熟悉了吧! 
    //打开数据库
    if (sqlite3_open([databaseFilePath UTF8String], &database)==SQLITE_OK) { 
            NSLog(@"sqlite dadabase is opened."); 
    }
    else{ return;}//打开不成功就返回

      在打开了数据库的前提下,如果数据库没有表,那就开始建表了哦!
    char *error; 
    const char *createSql="create table(id integer primary key autoincrement, name text)";
    if (sqlite3_exec(database, createSql, NULL, NULL, &error)==SQLITE_OK) { 
            NSLog(@"create table is ok."); 
    }
    else
    {
           NSLog(@"error: %s",error);
           sqlite3_free(error);//每次使用完毕清空error字符串,提供给下一次使用

    建表完成之后,就开始插入记录:

      const char *insertSql="insert into a person (name) values(‘gg’)"; 
    if (sqlite3_exec(database, insertSql, NULL, NULL, &error)==SQLITE_OK) { 
            NSLog(@"insert operation is ok."); 
    }

    else
    {
           NSLog(@"error: %s",error);
           sqlite3_free(error);//每次使用完毕清空error字符串,提供给下一次使用

      下一步,查询记录:

      const char *selectSql="select id,name from a person"; 
    sqlite3_stmt *statement; 
    if (sqlite3_prepare_v2(database,selectSql, -1, &statement, nil)==SQLITE_OK) { 
            NSLog(@"select operation is ok."); 
    }
    else
    {
           NSLog(@"error: %s",error);
           sqlite3_free(error);

    while(sqlite3_step(statement)==SQLITE_ROW) { 
    int _id=sqlite3_column_int(statement, 0); 
    NSString *name=(char*)sqlite3_column_text(statement, 1); 
    NSLog(@"row$amp;>amp;$gt;id %i, name %s",_id,name); 
    }
    sqlite3_finalize(statement);

      最后,关闭数据库:

      sqlite3_close(database); 

      注意:写入数据库,字符串可以采用char方式,而从数据库中取出char类型,当char类型有表示中文字符时,会出现乱码。这是因为数据库默认使用ascII编码方式。所以要想正确从数据库中取出中文,需要用NSString来接收从数据库取出的字符串。

    7.

    什么是沙盒?沙盒包含哪些文件,描述每个文件的使用场景。如何获取这些文件的路径?如何获取应用程序包 中文件的路径? 

     答:

    沙盒是某个iphone工程进行文件操作有此工程对应的指定的位置,不能逾越。 包括:四个文件夹:documents,tmp,app,Library。 手动保存的文件在documents文件里。 Nsuserdefaults保存的文件在tmp文件夹里。

    Documents 目录:您应该将所有de应用程序数据文件写入到这个目录下。这个目录用于存储用户数据或其它应该定期备 份的信息。AppName.app 目录:这是应用程序的程序包目录,包含应用程序的本身。由于应用程序必须经过签名,所以 您在运行时不能对这个目录中的内容进行修改,否则可能会使应用程序无法启动。Library 目录:这个目录下有两个子目 录:Caches 和 PreferencesPreferences 目录包含应用程序的偏好设置文件。您不应该直接创建偏好设置文件,而是 应该使用NSUserDefaults类来取得和设置应用程序的偏好.Caches 目录用于存放应用程序专用的支持文件,保存应用程 序再次启动过程中需要的信息。tmp 目录:这个目录用于存放临时文件,保存应用程序再次启动过程中不需要的信息。

    获取这些目录路径的方法:
    1,获取家目录路径的函数:
    NSString *homeDir = NSHomeDirectory();
    2,获取Documents目录路径的方法:
    NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docDir = [paths objectAtIndex:0];
    3,获取Caches目录路径的方法:
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *cachesDir = [paths objectAtIndex:0];
    4,获取tmp目录路径的方法:
    NSString *tmpDir = NSTemporaryDirectory();
    5,获取应用程序程序包中资源文件路径的方法:
    例如获取程序包中一个图片资源(apple.png)路径的方法:
    NSString *imagePath = [[NSBundle mainBundle] pathForResource:@”apple” ofType:@”png”]; UIImage *appleImage = [[UIImage alloc] initWithContentsOfFile:imagePath]; 代码中的mainBundle类方法用于返回一个代表应用程序包的对象。

  • 相关阅读:
    博客园
    未释放的已删除文件
    ssh连接缓慢
    剑指 Offer 38. 字符串的排列
    剑指 Offer 37. 序列化二叉树
    剑指 Offer 50. 第一个只出现一次的字符
    剑指 Offer 36. 二叉搜索树与双向链表
    剑指 Offer 35. 复杂链表的复制
    剑指 Offer 34. 二叉树中和为某一值的路径
    剑指 Offer 33. 二叉搜索树的后序遍历序列
  • 原文地址:https://www.cnblogs.com/jinchengvs/p/4869246.html
Copyright © 2011-2022 走看看