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了
先嘚瑟这么多,以后学习了新知识再补充,新手学习中,请勿拍砖,待续……