IOS中数据存储一般分为以下几种方式
1、NSString *home = NSHomeDirectory();
2、NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
方法1获取到了应用程序沙盒目录,进一步需要使用stringByAppendingString方法拼接出Documents的最终路径,这怎么说也有点繁琐。苹果给咱提供了第二种比较牛逼的方法,获取到的是一个Array对象,其实里面就一个文件夹,随意lastObject或firstObject都能靠谱的拿到,拼接个要存储到的文件名,直接write进去,直接看小弟的代码:
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,代码如下:
// 获取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.获取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.创建对象 /* 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协议里面定义的两个方法,这两个方法描述了如何对数据进行存储
// 当将一个自定义对象保存到文件的时候就会调用该方法 // 在该方法中说明如何存储自定义对象的属性 // 也就说在该方法中说清楚存储自定义对象的哪些属性 - (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实现协议的代码如下
- (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了
先嘚瑟这么多,以后学习了新知识再补充,新手学习中,请勿拍砖,待续……