iOS数据持久化

1.NSUserDefaults

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:@"大头" forKey:@"name"];
[userDefaults setBool:YES forKey:@"gender"];
[userDefaults setInteger:26 forKey:@"age"];

[userDefaults synchronize];//立即写入

NSString *name = [userDefaults objectForKey:@"name"];
BOOL gender = [userDefaults boolForKey:@"gender"];
NSInteger age = [userDefaults integerForKey:@"age"];
NSLog(@"%@ %d %ld",name,gender,age);

如果没有调用synchronize方法,系统会根据I/O情况不定时地保存到文件中

  1. plist文件(Property List,属性列表文件)
//document路径
NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
//plist文件路径
NSString *plistPath = [documentPath stringByAppendingPathComponent:@"userInfo.plist"];

NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
[userInfo setObject:@"大头" forKey:@"name"];
[userInfo setObject:@"1" forKey:@"gender"];
[userInfo setObject:@"26" forKey:@"age"];

[userInfo writeToFile:plistPath atomically:YES];//atomically:YES保证文件的写入原子性,会先创建一个临时文件,直到文件内容写入成功再导入到目标文件里,更安全
NSDictionary *uInfo = [NSDictionary dictionaryWithContentsOfFile:plistPath];
NSLog(@"%@",uInfo);

3.NSKeyedArchiver(归档)
归档可以存储遵循了NSCoding协议的对象
首先建一个Model类
UserModel.h

#import 

@interface UserModel : NSObject

@property (nonatomic, copy)NSString *userName;

@property (nonatomic, assign)BOOL userGender;

@property (nonatomic, assign)NSInteger userAge;

@end

UserModel.m
实现NSCoding的两个协议方法

#import "UserModel.h"

@implementation UserModel

//归档协议方法
- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:self.userName forKey:@"name"];
    [aCoder encodeBool:self.userGender forKey:@"gender"];
    [aCoder encodeInteger:self.userAge forKey:@"age"];
}

//解档协议方法
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super init]) {
        self.userName = [aDecoder decodeObjectForKey:@"name"];
        self.userGender = [aDecoder decodeBoolForKey:@"gender"];
        self.userAge = [aDecoder decodeIntegerForKey:@"age"];
    }
    return self;
}

@end

当属性比较多的时候可以用runtime来遍历属性列表完成归档和解档的协议方法:

#import "UserModel.h"
#import 

@implementation UserModel

//归档协议方法
- (void)encodeWithCoder:(NSCoder *)aCoder {
//    [aCoder encodeObject:self.userName forKey:@"name"];
//    [aCoder encodeBool:self.userGender forKey:@"gender"];
//    [aCoder encodeInteger:self.userAge forKey:@"age"];
    
    unsigned int ivarCount;
    Ivar *ivars = class_copyIvarList([self class], &ivarCount);
    for (unsigned i = 0; i < ivarCount; i++) {
        Ivar ivar = ivars[i];
        NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];
        [aCoder encodeObject:[self valueForKey:key] forKey:key];
    }
    free(ivars);
}

//解档协议方法
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
//    if (self = [super init]) {
//        self.userName = [aDecoder decodeObjectForKey:@"name"];
//        self.userGender = [aDecoder decodeBoolForKey:@"gender"];
//        self.userAge = [aDecoder decodeIntegerForKey:@"age"];
//    }
//    return self;
    
    if (self = [super init]) {
        unsigned int ivarCount;
        Ivar *ivars = class_copyIvarList([self class], &ivarCount);
        for (unsigned i = 0; i < ivarCount; i++) {
            Ivar ivar = ivars[i];
            NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];
            [self setValue:[aDecoder decodeObjectForKey:key] forKey:key];
        }
        free(ivars);
    }
    return self;
}

@end

存储:

NSString *userInfoFile = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"userModel.archiver"];

UserModel *userModel = [[UserModel alloc]init];
userModel.userName = @"大头";
userModel.userGender = YES;
userModel.userAge = 26;

[NSKeyedArchiver archiveRootObject:userModel toFile:userInfoFile];
//取出来看一下
UserModel *unarchiveModel = [NSKeyedUnarchiver unarchiveObjectWithFile:userInfoFile];
if (unarchiveModel) {
    NSLog(@"%@ %d %ld",unarchiveModel.userName,unarchiveModel.userGender,unarchiveModel.userAge);
}

也可以存自定义的数据:

NSString *userInfoFile = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"userModel.archiver"];

NSMutableData *archiverData = [NSMutableData data];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:archiverData];

UserModel *user1 = [[UserModel alloc]init];
user1.userName = @"user1";
user1.userGender = YES;
user1.userAge = 12;

UserModel *user2 = [[UserModel alloc]init];
user2.userName = @"user2";
user2.userGender = NO;
user2.userAge = 18;

[archiver encodeObject:user1 forKey:@"user1"];
[archiver encodeObject:user2 forKey:@"user2"];
[archiver finishEncoding];//完成归档
[archiverData writeToFile:userInfoFile atomically:YES];

//取出
NSData *userData = [NSData dataWithContentsOfFile:userInfoFile];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:userData];
UserModel *unarchiverUser1 = [unarchiver decodeObjectForKey:@"user1"];
UserModel *unarchiverUser2 = [unarchiver decodeObjectForKey:@"user2"];
[unarchiver finishDecoding];//完成解档
NSLog(@"%@ %d %ld  %@ %d %ld",unarchiverUser1.userName,unarchiverUser1.userGender,unarchiverUser1.userAge,unarchiverUser2.userName,unarchiverUser2.userGender,unarchiverUser2.userAge);

你可能感兴趣的:(iOS数据持久化)