首页 > 代码库 > IOS 数据存储
IOS 数据存储
IOS中数据存储一般分为以下几种方式
1、NSString *home = NSHomeDirectory();
2、NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
方法1获取到了应用程序沙盒目录,进一步需要使用stringByAppendingString方法拼接出Documents的最终路径,这怎么说也有点繁琐。苹果给咱提供了第二种比较牛逼的方法,获取到的是一个Array对象,其实里面就一个文件夹,随意lastObject或firstObject都能靠谱的拿到,拼接个要存储到的文件名,直接write进去,直接看小弟的代码:
1 2 3 4 5 6 7 | NSString *doc = [ NSSearchPathForDirectoriesInDomains ( NSDocumentDirectory , NSUserDomainMask , YES ) lastObject]; // 拼接文件路径 NSString *path = [doc stringByAppendingPathComponent:@ "abc.plist" ] ; NSArray *arr = @[@ "luseike" , @ "25" ]; [arr writeToFile:path atomically: YES ]; |
documents中已经出现了abc.plist(啰嗦句,documents里面存的是plist文件,这个你肯定知道,它本质上是XML文件。plist文件中能存储系统自带的一些数据类型,比如NSArray、NSString、NSNumber……,也就是用writeToFile方法的对象)
2、在来试试第二种存储方式吧,preference是专门用来存储应用程序的配置信息的。如果利用系统里的偏好设置来存储数据,默认是存储中Preference文件夹下面的,并且会将所有的数据保存到同一文件中。
它具体的使用方法是利用NSUserDefaults对象,每个应用都有自己的UserDefault,代码如下:
1 2 3 4 5 6 7 | // 获取NSUserDefaults对象 NSUserDefaults *defaults = [ NSUserDefaults standardUserDefaults]; // 保存数据(如果设置数据之后没有同步, 会在将来某一时间点自动将数据保存到Preferences文件夹下面) [defaults setObject:@ "luseike" forKey:@ "name" ]; [defaults setObject:@ "man" forKey:@ "gender" ]; [defaults setInteger:13 forKey:@ "age" ]; [defaults setDouble:10.1 forKey:@ "height" ]; |
preference下面存储的数据不会立即更新,你可以手动同步下,[defaults synchronize]; 轻松搞定。保存的时候是set进去的,读取的时候当然也要按照这个套路来才行,上代码:
1 2 3 4 5 6 7 | // 1.获取NSUserDefaults NSUserDefaults *defaults = [ NSUserDefaults standardUserDefaults]; // 2.通过NSUserDefaults获取保存的数据 NSString *name = [defaults objectForKey:@ "name" ]; int age = [defaults integerForKey:@ "age" ]; NSLog (@ "%@" , name); NSLog (@ "%d" , age); |
苹果居然给我们提供了逆天的integerForKey,当然还有floatFor、doubleFor……
3、上面这两种方式都只能存储系统自带的数据类型,如果要存我们自定义的数据类型,就有点尴尬了,这就不得不邪恶的搬出第三种方式了
NSKeyedArchiver这哥们牛逼的很,自定义一个Person类,有name、age、height三个属性,来看看NSKeyedArchiver怎么存储
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // 1.创建对象 /* NJPerson *p = [[NJPerson alloc] init]; p.name = @"lnj"; p.age = 28; p.height = 1.76; */ NJStudent *stu = [[NJStudent alloc] init]; stu.name = @ "luseike" ; stu.age = 25; stu.height = 1.8; stu.weight = 60; // 2.获取文件路径 NSString *docPath = [ NSSearchPathForDirectoriesInDomains ( NSDocumentDirectory , NSUserDomainMask , YES ) lastObject]; NSString *path = [docPath stringByAppendingPathComponent:@ "stu.xxoo" ]; NSLog (@ "path = %@" , path); // 3.将自定义对象保存到文件中 // [NSKeyedArchiver archiveRootObject:p toFile:path]; [ NSKeyedArchiver archiveRootObject:stu toFile:path]; |
这么使用,有一个条件,那就是要存储的类型必须实现NSCoding协议里面定义的两个方法,这两个方法描述了如何对数据进行存储
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // 当将一个自定义对象保存到文件的时候就会调用该方法 // 在该方法中说明如何存储自定义对象的属性 // 也就说在该方法中说清楚存储自定义对象的哪些属性 - ( void )encodeWithCoder:( NSCoder *)encoder { NSLog (@ "NJPerson encodeWithCoder" ); [encoder encodeObject: self .name forKey:@ "name" ]; [encoder encodeInteger: self .age forKey:@ "age" ]; [encoder encodeFloat: self .height forKey:@ "heigth" ]; } // 当从文件中读取一个对象的时候就会调用该方法 // 在该方法中说明如何读取保存在文件中的对象 // 也就是说在该方法中说清楚怎么读取文件中的对象 - ( id )initWithCoder:( NSCoder *)decoder { NSLog (@ "NJPerson initWithCoder" ); if ( self = [ super init]) { self .name = [decoder decodeObjectForKey:@ "name" ]; self .age = [decoder decodeIntegerForKey:@ "age" ]; self .height = [decoder decodeFloatForKey:@ "heigth" ]; } return self ; } |
还有一点需要注意,如果一个类继承了Person类,子类中添加的属性是保存不成功的,子类必须重写协议方法才可以。比如定义了继承Person类的Student类,新增weight属性,Student实现协议的代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | - ( void )encodeWithCoder:( NSCoder *)aCoder { [ super encodeWithCoder:aCoder]; NSLog (@ "NJStudent encodeWithCoder" ); [aCoder encodeFloat: self .weight forKey:@ "weight" ]; } - ( id )initWithCoder:( NSCoder *)aDecoder { if ( self = [ super initWithCoder:aDecoder]) { NSLog (@ "NJStudent initWithCoder" ); self .weight = [aDecoder decodeFloatForKey:@ "weight" ]; } return self ; } |
然后像保存Person一样的方式就能正常保存Student了
先嘚瑟这么多,以后学习了新知识再补充,新手学习中,请勿拍砖,待续……