iOS应用数据存储的常用方式有

1.plist文件。2 .Preference(偏好设置)。 3.NSKeyArchiver归档(NSCoding)4.数据库存储(SQLite3 当有大量的数据需要存储时使用)。


今天我们只讲前面三中,数据库后面在说。

讲之前要先了解一下沙盒(sandbox),每个软件都有自己的应用沙盒(应用沙盒就是应用的文件夹),与其它文件系统隔离。应用必须待在自己的沙盒里,

其它应用不能访问该沙盒。应用沙盒的文件系统目录如下图:

     

沙盒中各文件夹的作用

  • Documents:保存应用运行时生成的需要持久化的数据,iTunes同步设备时会备份该目录。例如,游戏应用可将游戏存档保存在该目录。保存相对重要的数据。

  • tmp:保存应用运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除。应用没有运行时,系统也可能会清除该目录下的文件。iTunes同步设备时不会备份该目录。保存不重要的并且大的数据。

  • Library/Caches:保存应用运行时生成的需要持久化的数据,iTunes同步设备时不会备份该目录。一般存储体积大、不需要备份的非重要数据

  • Library/Preference:保存应用的所有偏好设置,iOS的Settings(设置)应用会在该目录中查找应用的设置信息。iTunes同步设备时会备份该目录。该目录由系统管理, 无需我们来管理。通常用来存储一些基本的软件配置信息, 比如记住密码、自动登录等。

获取沙盒路径

NSLog(@"沙盒路径==%@",NSHomeDirectory());


注意要和bundle路径区分开,别搞混淆了

NSLog(@"bundlePath======%@",[NSBundlemainBundle].bundlePath);


bundle路径应用程序的根路径,比如获取项目info.plist文件,通过bundle路径去拿。


获取documents文件夹路径


NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)lastObject];

第一个参数:目标文件。第二个参数:作用域,第三个参数:是否展开~。

获取caches文件夹路径

NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES)lastObject];



获取tmp文件夹路径

NSString *tempPath =NSTemporaryDirectory();

直接通过方法去获取。

那先讲第一种plist文件存储(主要存储有writeToFile方法的对象,比如NSArray NSDictionary NSString NSData 对象);

NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,               NSUserDomainMask,YES)lastObject];
    NSArray *names = [NSArrayarrayWithObjects:@"Jack",@"Rose",@"Tom"];
    NSString *file = [documentPathstringByAppendingPathComponent:@"name.plist"];
     //参数2:是否允许原子型写入
    [names writeToFile:fileatomically:YES];

 plist文件的读取
 
    NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) lastObject];
    NSString *file = [documentPathstringByAppendingPathComponent:@"name.plist"];
    NSArray *names = [NSArrayarrayWithContentsOfFile:file];

偏好设置存储(本质还是一个plist文件)

NSUserDefaults *defaults = [NSUserDefaultsstandardUserDefaults];
    [defaults setBool:YESforKey:@"isAutoLogin"];
    [defaults setObject:@"wululin"forKey:@"userName"];
    [defaults setObject:@"560560"forKey:@"password"];
    [defaults synchronize];


记得要调用 synchronize.


偏好设置读取


 

NSUserDefaults *defaults = [NSUserDefaultsstandardUserDefaults];
    BOOL  isAuto = [defaultsboolForKey:@"isAutoLogin"];
    NSString *name = [defaultsobjectForKey:@"userName"];
    NSString *password = [defaultsobjectForKey:@"password"];



归档

对象要归档,首先要遵守NSCoding协议,然后实现encodeWithCoder方法,告诉系统哪些属性需要归档。

创建一个Person类 遵守NSCoding协议。


#import <Foundation/Foundation.h>
@interface Person :NSObject<NSCoding>
@property(nonatomic,copy)NSString *name;
@property(nonatomic,copy)NSString *phone;
@end


实现encodeWithCoder方法

@implementation Person
//归档 告诉系统要存储哪些属性
-(void) encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:self.nameforKey:@"name"];
    [aCoder encodeObject:self.phoneforKey:@"phone"];
}
@end
 
用NSKeyedArchiver将对象写入文件

 NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
    
    NSString *filePath = [path stringByAppendingPathComponent:@"person.plist"];
    
    [NSKeyedArchiver archiveRootObject:person toFile:filePath];
 

反归档
实现initWithCoder方法

//反归档读取对象的哪些属性
-(instancetype) initWithCoder:(NSCoder *)aDecoder {
    
    if(self == [superinit]) {
        self.name = [aDecoderdecodeObjectForKey:@"name"];
        self.phone = [aDecoderdecodeObjectForKey:@"phone"];
    }
    returnself;
}
NSKeyedUnarchiver将文件转化成对象
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)lastObject];
    
    NSString *filePath = [pathstringByAppendingPathComponent:@"person.plist"];
    
    [NSKeyedArchiverarchiveRootObject:persontoFile:filePath];
    
    
    Person *p = [NSKeyedUnarchiverunarchiveObjectWithFile:filePath];