美文网首页
iOS数据持久化小结

iOS数据持久化小结

作者: Andy_Ron | 来源:发表于2018-08-23 23:21 被阅读68次

    持久化就是把数据保存在硬盘上而不是内存里,程序重启后数据不会消失。iOS中数据持久化方法有:plist文件(属性列表)UserDefaultsNSKeyedArchiver(归档)SQLite3CoreData等,另外还有FMDB(用OC封装的SQLite库)、realm(代替SQLite3CoreData新的数据库)。

    plist

    某些特定的数据类型,可以通过XML形式存储成plist文件。
    这些数据类型都有write(ToFile:)方法,包括:

    NSArray;
    NSMutableArray;
    NSDictionary;
    NSMutableDictionary;
    NSData;
    NSMutableData;
    NSString;
    NSMutableString;
    NSNumber;
    NSDate;
    

    示例代码:

    // 获得路径
    let fileManager = FileManager.default
    let path = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first
    let fileName = path?.appendingPathComponent("test.plist")
    
    // 存储。  其中atomically表示是否需要先写入一个辅助文件,再把辅助文件拷贝到目标文件地址。这是更安全的写入文件方法,一般都写true。
    let arr: NSArray = [123, 34]
    try? arr.write(toFile: (fileName?.path)!, atomically: true)
    
    // 读取
    let res = NSArray(contentsOfFile: (fileName?.path)!)
    
    print((fileName?.path)!)
    print(res)
    

    UserDefaults

    // 获得UserDefaults文件
    let userDefaults = UserDefaults.standard
    
    // 向文件中写入内容
    userDefaults.set("Andy", forKey: "name")
    userDefaults.set("male", forKey: "sex")
    userDefaults.set(100, forKey: "age")
    // 立即保存
    userDefaults.synchronize()
    // 读取文件
    let name = userDefaults.object(forKey: "name")
    let sex = userDefaults.object(forKey: "sex")
    let age = userDefaults.object(forKey: "age")
    
    print(name, sex, age)
    
    • 如果没有调用synchronize方法,系统会根据I/O情况不定时刻地保存到文件中。所以如果需要立即写入文件的就必须调用synchronize方法.
    • UserDefaults适合存储少量的本地数据,比如要保存一个登陆界面的数据,用户名、密码之类的。
    • 相对于plist文件,UserDefaults保存数据方便,不需要创建文件,读取文件。
    • UserDefaults保存的数据也是plist类型文件,在目录Library/Preferences/里。

    NSKeyedArchiver(归档)

    遵循了NSCoding协议的对象都可以通过NSKeyedArchiver实现序列化

    • 实现NSCoding协议的两个方法
    //解档
    - (id)initWithCoder:(NSCoder *)aDecoder {
        if ([super init]) {
            self.name = [aDecoder decodeObjectForKey:@"name"];
            self.sex = [aDecoder decodeObjectForKey:@"sex"];
            self.age = [aDecoder decodeIntegerForKey:@"age"];
        }
        
        return self;
    }
    
    //归档
    - (void)encodeWithCoder:(NSCoder *)aCoder {
        [aCoder encodeObject:self.name forKey:@"name"];
        [aCoder encodeObject:self.sex forKey:@"sex"];
        [aCoder encodeInteger:self.age forKey:@"age"];
    }
    
    • 归档后的对象存储和读取
    - (void)save {
        NSString *file = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"person.data"];
        
        Person *person = [[Person alloc] init];
        person.sex = @"male";
        person.name = @"Andy";
        person.age = 100;
        
        [NSKeyedArchiver archiveRootObject:person toFile:file];
    }
    
    - (void)get {
        NSString *file = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"person.data"];
        
        Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:file];
        if (person) {
            NSLog(@"name: %@, sex: %@, age: %ld", person.name, person.sex, (long)person.age);
        }
    
    }
    

    SQLite3

    1. 打开数据库并创建一个表
    /**
     *  打开数据库并创建一个表
     */
    - (void)openDatabase {
        
        //1.设置文件名
        NSString *filename = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"person.db"];
        
        //2.打开数据库文件,如果没有会自动创建一个文件
        NSInteger result = sqlite3_open(filename.UTF8String, &_sqlite3);
        if (result == SQLITE_OK) {
            NSLog(@"打开数据库成功!");
            
            //3.创建一个数据库表
            char *errmsg = NULL;
            
            sqlite3_exec(_sqlite3, "CREATE TABLE IF NOT EXISTS t_person(id integer primary key autoincrement, name text, age integer)", NULL, NULL, &errmsg);
            if (errmsg) {
                NSLog(@"错误:%s", errmsg);
            } else {
                NSLog(@"创表成功!");
            }
            
        } else {
            NSLog(@"打开数据库失败!");
        }
    }
    
    1. 插入数据
    /**
     *  往表中插入1000条数据
     */
    - (void)insertData {
        
        NSString *nameStr;
        NSInteger age;
        for (NSInteger i = 0; i < 1000; i++) {
            nameStr = [NSString stringWithFormat:@"andy-%d", arc4random_uniform(10000)];
            age = arc4random_uniform(80) + 20;
            
            NSString *sql = [NSString stringWithFormat:@"INSERT INTO t_person (name, age) VALUES('%@', '%ld')", nameStr, age];
            
            char *errmsg = NULL;
            sqlite3_exec(_sqlite3, sql.UTF8String, NULL, NULL, &errmsg);
            if (errmsg) {
                NSLog(@"错误:%s", errmsg);
            }
        }
        
        NSLog(@"插入完毕!");
    }
    
    1. 读取数据
    /**
     *  从表中读取数据
     */
    - (void)readData {
        NSMutableArray *mArray = [NSMutableArray arrayWithCapacity:1000];
        char *sql = "select name, age from t_person;";
        sqlite3_stmt *stmt;
    
        NSInteger result = sqlite3_prepare_v2(_sqlite3, sql, -1, &stmt, NULL);
        if (result == SQLITE_OK) {
            while (sqlite3_step(stmt) == SQLITE_ROW) {
    
                char *name = (char *)sqlite3_column_text(stmt, 0);
                NSInteger age = sqlite3_column_int(stmt, 1);
                NSLog(@"name: %s, age: %d", name, age);
    
          
            }
        }
        sqlite3_finalize(stmt);
    }
    

    CoreData

    之前的笔记:开始用Swift开发iOS 10 - 17 使用Core Data

    代码:LearniOSByProject/115-PersistData

    参考: 我要永远地记住你!(iOS中几种数据持久化方案)

    相关文章

      网友评论

          本文标题:iOS数据持久化小结

          本文链接:https://www.haomeiwen.com/subject/fnfmiftx.html