iOS 本地存储方法了解下

常用的集中方式:
NSUserDefaults类
Plist文件
解归档
FMDB
CoreData/sqlite
第三方数据存储框架(realm)

1、NSUserDefaults类
常用情景:一般对于一些基本的用户设置,因为数据量很小,我们可以使用OC语言中的 NSUserDefaults类来进行处理。使用方法很简单,只需要调用类中的方法即可

NSMutableArray *mutArr = [[NSMutableArray alloc]initWithObjects:@"1", nil];

    //存入数组并同步

[[NSUserDefaults standardUserDefaults] setObject:mutArr forKey:@"mutableArr"];

[[NSUserDefaults standardUserDefaults] synchronize];

    //读取存入的数组 打印

NSArray *arr = [[NSUserDefaults standardUserDefaults] objectForKey:@"mutableArr"];

NSLog(@"%@",arr);

NSUserDefaults类除了可以存储数组、字典、NSdata外,还可以直接存储OC基本类型属性。但是不能直接作用到自定义对象,如果是自定义对象需要进行归档操作。

2、Plist文件
Plist文件作为Xcode的一种资源包,也可以作为一种存储工具。
在项目中创建Plist文件。 在项目中创建的好处是文件的可视化,我们可以很直观的看到文件的内容,同时Xcode还提供了直接操作文件的功能。便于我们对文件内容的增删改查。这种方式的缺点是项目中的plist文件一般作为固态的数据形势保存,对于经常需要改动的数据就不好操作了。

iOS 本地存储方法了解下_第1张图片
创建plist文件.png
NSString *string = [[NSBundle mainBundle] pathForResource:@"testPlist" ofType:@"plist"];

NSDictionary *dic = [NSDictionary dictionaryWithContentsOfFile:string];

NSLog(@"%@",dic);   //打印文件中的内容
代码读写Plist文件。避免了在项目中创建Plist文件导致不便更改的麻烦。
//创建一个plist文件  testPlist
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
    NSString *plistpath = [paths objectAtIndex:0];
    NSLog(@"path = %@",plistpath);
    NSString *filename=[plistpath stringByAppendingPathComponent:@"testPlist.plist"];
    NSFileManager* fm = [NSFileManager defaultManager];
    [fm createFileAtPath:filename contents:nil attributes:nil];
    
    //写入内容
    NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"test",nil];
    [dic writeToFile:filename atomically:YES];
    
    //读文件
    NSDictionary* dic2 = [NSDictionary dictionaryWithContentsOfFile:filename];
    NSLog(@"dic is:%@",dic2);

例子:

iOS 本地存储方法了解下_第2张图片
例子.png
#import "ViewController.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITextField *nameTF;
@property (weak, nonatomic) IBOutlet UITextField *sexTF;
@property (weak, nonatomic) IBOutlet UITextField *ageTF;
@property (weak, nonatomic) IBOutlet UILabel *showL;

@property (nonatomic,copy) NSString *filePath;
@property (nonatomic,copy) NSFileManager * manager;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    NSString *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    _filePath = [paths stringByAppendingPathComponent:@"account.plist"];
    _manager = [NSFileManager defaultManager];
    [_manager createFileAtPath:_filePath contents:nil attributes:nil];
    NSLog(@"%@",_filePath);
}

- (IBAction)saveThing:(id)sender {
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    [dic setObject:self.nameTF.text forKey:@"name"];
    [dic setObject:self.sexTF.text forKey:@"sex"];
    [dic setObject:self.ageTF.text forKey:@"age"];
    [dic writeToFile:_filePath atomically:YES];
    
}
- (IBAction)showAction:(id)sender {
    NSDictionary *dic = [NSDictionary dictionaryWithContentsOfFile:_filePath];
    self.showL.text = [NSString stringWithFormat:@"大家好,我叫%@,%@,今年%@岁",dic[@"name"],dic[@"sex"],dic[@"age"]];
}

- (IBAction)removeAction:(id)sender {
    [_manager removeItemAtPath: _filePath error:nil];
}


@end

3、解归档
不管是NSUserDefaults 或者是 plist 都不能对自定义的对象进行存储,OC提供了解归档恰好解决这个问题。 解归档针对的是一个对象,假设我们现在有一个AccountModel的类,需要进行归档和接档,上代码。(用来存储用户的基本信息最好不过了)

//AccountModel.h文件 遵守NSCoding协议,很重要
#import 

@interface AccountModel : NSObject

@property (nonatomic,copy) NSString *name;
@property (nonatomic,copy) NSString *sex;
@property (nonatomic,copy) NSString *age;

@end
//AccountModel.m文件
#import "AccountModel.h"

@implementation AccountModel

- (void)encodeWithCoder:(NSCoder *)aCoder{
    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeObject:self.age forKey:@"age"];
    [aCoder encodeObject:self.sex forKey:@"sex"];
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder{
    if (self = [super init]) {
        self.name = [aDecoder decodeObjectForKey:@"name"];
        self.age = [aDecoder decodeObjectForKey:@"age"];
        self.sex = [aDecoder decodeObjectForKey:@"sex"];
    }
    return self;
}

@end

接下来只要使用解/归档辅助类就可以AccountModel类进行解归档

//AccountTool.h文件
#import 
#import "AccountModel.h"

@interface AccountTool : NSObject

+ (AccountModel *)getAccount;
+ (void)save:(AccountModel *)model;
+ (void)update:(AccountModel *)model;
+ (void)remove;
@end
//AccountTool.m文件
#import "AccountTool.h"

@implementation AccountTool


+ (AccountModel *)getAccount{
    
    return [NSKeyedUnarchiver unarchiveObjectWithFile:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"account.plist"]];
}

+ (void)save:(AccountModel *)model{
    [NSKeyedArchiver archiveRootObject:model toFile:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"account.plist"]];
    NSLog(@"%@",[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"account.plist"]);
}

+ (void)update:(AccountModel *)model{
    [[self class] remove];
    [[self class] save:model];
}

+ (void)remove{
    NSFileManager *manager = [NSFileManager defaultManager];
    [manager removeItemAtPath:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"account.plist"] error:nil];
}
@end
//viewcontroller.m中
#import "ViewController.h"
#import "AccountModel.h"
#import "AccountTool.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITextField *nameTF;
@property (weak, nonatomic) IBOutlet UITextField *sexTF;
@property (weak, nonatomic) IBOutlet UITextField *ageTF;
@property (weak, nonatomic) IBOutlet UILabel *showL;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (IBAction)saveThing:(id)sender {
    AccountModel *model = [AccountModel new];
    model.name = self.nameTF.text;
    model.sex = self.sexTF.text;
    model.age = self.ageTF.text;
    [AccountTool save:model];
    
}
- (IBAction)showAction:(id)sender {
    AccountModel *account = [AccountTool getAccount];
    self.showL.text = [NSString stringWithFormat:@"大家好,我叫%@,%@,今年%@岁",account.name,account.sex,account.age];
}

- (IBAction)removeAction:(id)sender {
    [AccountTool remove];
}
@end

4、手动存入沙盒
iphone沙箱模型的有四个文件夹,分别是documents,tmp,app,Library。
1、Documents 目录:您应该将所有的应用程序数据文件写入到这个目录下。这个目录用于存储用户数据或其它应该定期备份的信息。为了不让App的备份过于庞大,我们不建议在这里存放大容量的文件。
2、AppName.app 目录:这是应用程序的程序包目录,包含应用程序的本身。由于应用程序必须经过签名,所以您在运行时不能对这个目录中的内容进行修改,否则可能会使应用程序无法启动。
3、Library 目录:这个目录下有两个子目录:Caches 和 Preferences
Preferences 目录:包含应用程序的偏好设置文件。您不应该直接创建偏好设置文件,而是应该使用NSUserDefaults类来取得和设置应用程序的偏好.
Caches 目录:用于存放应用程序专用的支持文件,保存应用程序再次启动过程中需要的信息。细心的话你会发现几乎所有的第三方框架的缓存信息处理都在这个文件中,一般的大容量文件都放在这里。
4、tmp 目录:这个目录用于存放临时文件,保存应用程序再次启动过程中不需要的信息。Nsuserdefaults保存的文件一般在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(); 


//假设我们需往cache 存入数据,并命名为test的txt格式文件中
    NSString *filePath = [cachesDir stringByAppendingPathComponent:@"test.txt"];
    NSArray *dic = [[NSArray alloc] initWithObjects:@"test",@"test1" ,nil];
    
    if([dic writeToFile:filePath atomically:YES]){
        NSLog(@"存入成功");
    }
    //取出数据 打印
    NSLog(@"%@",[NSArray arrayWithContentsOfFile:filePath]);

5、FMDB
这个可以参考这里
GitHub小案例传送门

iOS 本地存储方法了解下_第3张图片
存储列表数据.png

你可能感兴趣的:(iOS 本地存储方法了解下)