/**
* NSUserDefaults 它是OC中一种单例对象,在一个工程里面(一个程序里面),它只有一个实例对象。无论你创建多少次,结果指针都会指向同一个地址,也就是只有一个实例对象,正因为如此,所以他能永久存储本地数据,简单实用。
* 但是,它只能储存一些简单的轻量级的数据,比如本地数据的用户名和密码,收藏的网址,它是首选。
* 当数据重复次数较多量很大的情况下,还是使用SQLite 存储,
* 虽然NSUserDefaults 同样可以存储这么多数据,相比较而言会麻烦很多。
它支持的数据类型有:NSNumber(NSInteger、float、double,int),
NSString,NSData,NSArray,NSDictionary,BOOL.
*/
//NSUserDefaults 这么实用,那它是怎么保存数据的呢?我们该如何将以上类型的数据保存下来?
/———————-NSNumber———————/
//例如保存一个NSNumber的对象和怎样取出对象。
//存储方法
NSNumber *num = [NSNumber numberWithInteger:20];
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];//实用便利构造器方法创建对象
[user setObject:num forKey:@”aNum”];//保存成功
//取出方法
NSUserDefaults *user11 = [NSUserDefaults standardUserDefaults];//虽然对象名字不同,但是指向同一个地址,数据是相同的,这就是单例的特性。
用user11 同样能取出 数据对象20。(下面同样使用user保存,使用user11取出数据,体现它的单例特性)
NSNumber *num11 = [user11 objectForKey:@”aNum”];//取出数据对象。
NSLog(@”>>>>>>>%@”,num11);//打印结果完全相同。
/**
* 细心的可能发现了它使用的方法和字典很像,其实他有很多方法都跟字典很像,
* 这样就有助于理解NSUserDefaults。
*/
/———————-NSString———————/
//例如保存一个NSString类型的对象
NSString *string = @"小明";
//因为NSUserDefaults是单例就直接使用上面的对象进行操作。
[user setObject:string forKey:@"aPerson"];
NSString *str = [user11 objectForKey:@"aPerson"];
NSLog(@"%@",str);
//打印结果也是相同
/———————-NSArray———————/
//例如保存一个NSArray
NSArray *array = [NSArray arrayWithObjects:@"123",@"小明",@"345", nil];
[user setObject:array forKey:@"数组"];
NSArray *arr = [user11 objectForKey:@"数组"];
NSLog(@"%@",arr);
//打印结果也是相同
//NSArray子类-可变数组NSMutableArray 类型的对象同样可以储存。如下:
NSMutableArray *array1 = [NSMutableArray arrayWithObjects:@"123",@"小明",@"345", nil];
[user setValue:array1 forKey:@"可变数组"];
//但是需要注意的是,它取出的数组只能是不可变的数组所以要用不可变数组接收。
即使你使用可变数组接收,运行时系统仍然返回的时不可变数组,
如果想要对数组数据进行删除添加等操作必须转换成可变数组。
NSArray *arr1 = [user11 objectForKey:@"数组"];
NSLog(@"%@",arr1);
//打印的结果也是相同
NSMutableArray *arr2 = [NSMutableArray arrayWithArray:arr1];
//这样转换后就可以对数组arr2进行添加删除操作了。
这时,你会想,要是想改变NSUserDefaults中保存的数据怎么办?
因为它和字典很像,key是唯一的,
可以使用同一个key再往NSUserDefaults里面存你已经改变过数据的数组,
NSUserDefaults就会因为key相同,进行一次覆盖操作,
结果就达到我们想要的结果。
[user setObject:arr2 forKey:@"数组"];
/———————-NSDictionary———————/
//使用上面的方法同样可以存储一个字典对象
NSDictionary *dict = [NSDictionary dictionaryWithObject:@”123” forKey:@”一个字符串”];
[user setObject:dict forKey:@”字符串字典”];
NSDictionary *dict1 = [user11 objectForKey:@”字符串字典”];
NSLog(@”%@”,dict1);
//打印结果也是相同
/————————NSData————————/
//因为NSUserDefaults 存储的数据类型有限,那么想要存储一个自定义对象该如何存储?
//方法一
//这个时候我们就可以使用归档方法来转换一个自定义Person类对象成NSData,
然后就可以用NSUserDefaults 进行保存了.
要使用NSDtata转换保存就要让Person接收协议并且实现协议的两个方法如下:
Person *p1 = [[Person alloc] init];
p1.name = @"小明";
p1.sex = @"boy";
Person *p2 = [[Person alloc] init];
p2.name = @"小红";
p2.sex = @"girl";
//将一个Person类对象转换成一个NSData类型对象,然后进行存储。
NSData *data1 = [NSKeyedArchiver archivedDataWithRootObject:p1];
[user setObject:data1 forKey:@"一个人小明"];//成功保存一个人信息。
//取出这个人信息的方法
NSData *personData = [user11 objectForKey:@"一个人小明"];
Person *person = [NSKeyedUnarchiver unarchiveObjectWithData:personData];
NSLog(@"name:%@ sex:%@",person.name,person.sex);
//打印这个取出人的信息就是小明信息。
//如何将一群人的信息保存下来呢?
//上面我们已经会使用归档将一个人转换成NSData类型数据,
一群的同样可以转换成一组NSDtata类型对象数据(转换使用for循环,
一个一个转换不现实),我们使用上面的俩人展示。
NSData *data2 = [NSKeyedArchiver archivedDataWithRootObject:p2];
NSArray *personArr = [NSArray arrayWithObjects:data1,data2, nil];
[user setObject:personArr forKey:@"两个人"];//这样两个人信息就被保存了。
//至于怎么取出,我想看了上面的,应该会了。
(转换成Person类型时同样使用归档取数据[NSKeyedUnarchiver unarchiveObjectWithData:(NSData *)]).
//方法二
//既然NSUserDefaults 可以存储数组字典,
那么自定义Person类型对象可不可以把他们自身的属性当成字符串存储在数组或者字典中,
然后进行存储呢?答案是肯定的。(但是要注意,这里并不是把自定义对象保存在数组或字典中然后进行存储,
而是把自定义对象属性当成字符串进行的保存,
因为NSUserDefaults 不支持自定义对象的保存)
//首先用自定义Person类创建对象。
Person *p3 = [[Person alloc] init];
p3.name = @"张三";
p3.sex = @"man";
//把一个人看成一个数组,
NSArray *aPerson = [NSArray arrayWithObjects:p3.name,p3.sex, nil];//和上面的数组存储相同。
[user setObject:aPerson forKey:@"aPerson"];
//这样就可以把自定义对象转换后进行保存,其实质还是保存的数组中的NSString类型的数据。和归档是不同的
/**
* 既然能存储数据,当然能删除数据。上面有说过他很像字典,所以删除的方法也很简单。
*/
//使用key来删除数据。
[user removeObjectForKey:(NSString *)];
//以上就是个人对NSUserDefaults 个人见解,楼主初学,如有不足之处还请谅解并指出,总之,NSUserDefaults 在我们编写代码中是最常用的一个永久保存数据的方法,也是最简单的,它还有很多中使用方法,楼主学的也不深,有兴趣的可以可以自己试试NSUserDefaults其他的方法。(例如使用[user dictionaryRepresentation];返回的是一个字典,同样有返回数组的方法。)