NSUserDefaults是一个单例,并且线程安全。它支持的数据类型有:NSNumber(NSInteger、float、double...),NSString,NSDate,NSArray,NSDictionary,BOOL...
NSArry和NSDictionary中存储的也只能是上面这些,不能存储自定义类型,除非自定义类型遵守NSCoding协议并实现相应的方法。
1、先看一下NSUserDefaults里面默认存储的东西
//获取设备上所有NSUserDefaults的设置
NSDictionary * userDefaultsDict = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
NSLog(@"%@", userDefaultsDict);
输出:
2015-11-11 11:03:20.055 01-nsuserdefaults[1035:41606] {
AddingEmojiKeybordHandled = 1;
AppleITunesStoreItemKinds = (
podcast,
artist,
"itunes-u",
booklet,
document,
movie,
eBook,
software,
"software-update",
"podcast-episode"
);
AppleLanguages = (
"en-US"
);
AppleLanguagesDidMigrate = "9.1";
AppleLocale = "en_US";
ApplePasscodeKeyboards = (
"en_US"
);
MSVLoggingMasterSwitchEnabledKey = 0;
NSInterfaceStyle = macintosh;
NSLanguages = (
"en-US",
en
);
}
具体信息不再详细解释,因为我也不是很清楚,0..0
2、NSUserDefaults支持的数据类型
NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults];
int testInt = 20;
float testFloat = 21.00;
double testDouble = 22.000000;
[userDefaults setInteger:testInt forKey:@"testInt"];
[userDefaults setDouble:testDouble forKey:@"testDouble"];
[userDefaults setFloat:testFloat forKey:@"testFloat"];
BOOL testBool = YES;
[userDefaults setBool:testBool forKey:@"testBool"];
NSString * testString = @"testNSString";
[userDefaults setObject:testString forKey:@"testString"];
//NSData读取一张图片
//不能存NSMutableData
NSString * jpgPath = [[NSBundle mainBundle] pathForResource:@"test1" ofType:@"jpg"];
NSData * testData = [NSData dataWithContentsOfFile:jpgPath];
[userDefaults setObject:testData forKey:@"testData"];
//日期
NSDate * testDate = [NSDate date];
[userDefaults setObject:testDate forKey:@"testDate"];
//不能存NSMutableArray
NSArray * testArray = @[@"t1", @"t2", @"t3"];
[userDefaults setObject:testArray forKey:@"testArray"];
//不能存NSMutableDictionary
NSDictionary * testDict = @{@"key1":@"value1", @"key2":@"value2", @"key3":@"value3"};
[userDefaults setObject:testDict forKey:@"testDict"];
[userDefaults synchronize];//同步一下,不写也可以
//注:
//总之不能存可变类型,取的时候也不能用可变类型接收,否则可变类型也变为不可变类型
//取数据
NSInteger fetchInt = [userDefaults integerForKey:@"testInt"];
NSLog(@"fetch int - %li", (long)fetchInt);
float fetchFloat = [userDefaults floatForKey:@"testFloat"];
NSLog(@"fetch float - %f", fetchFloat);
double fetchDouble = [userDefaults doubleForKey:@"testDouble"];
NSLog(@"fetch double - %f", fetchDouble);
BOOL fetchBool = [userDefaults boolForKey:@"testBool"];
NSLog(@"fetch bool - %i", fetchBool);
NSString * fetchStr = [userDefaults stringForKey:@"testString"];
NSLog(@"fetch NSString - %@", fetchStr);
//取出图片并显示
NSData * fetchData = [userDefaults dataForKey:@"testData"];
UIImage * image = [UIImage imageWithData:fetchData];
UIImageView * imageView = [[UIImageView alloc] initWithFrame:CGRectMake(50, 100, 200, 200)];
imageView.image = image;
imageView.backgroundColor = [UIColor orangeColor];
[self.view addSubview:imageView];
//读取日期类型数据
NSDate * fetchDate = [userDefaults valueForKey:@"testDate"];
NSLog(@"fetch Date - %@", fetchDate);
NSArray * fetchArray = [userDefaults arrayForKey:@"testArray"];
NSLog(@"fetch NSArray - %@", fetchArray);
NSDictionary * fetchDict = [userDefaults dictionaryForKey:@"testDict"];
NSLog(@"fetch NSDictionary - %@", fetchDict);
输出:
2015-11-11 12:10:57.269 01-nsuserdefaults[1595:72935] fetch int - 20
2015-11-11 12:10:57.270 01-nsuserdefaults[1595:72935] fetch float - 21.000000
2015-11-11 12:10:57.270 01-nsuserdefaults[1595:72935] fetch double - 22.000000
2015-11-11 12:10:57.271 01-nsuserdefaults[1595:72935] fetch bool - 1
2015-11-11 12:10:57.271 01-nsuserdefaults[1595:72935] fetch NSString - testNSString
2015-11-11 12:10:57.324 01-nsuserdefaults[1595:72935] fetch Date - 2015-11-11 04:10:57 +0000
2015-11-11 12:10:57.324 01-nsuserdefaults[1595:72935] fetch NSArray - (
t1,
t2,
t3
)
2015-11-11 12:10:57.324 01-nsuserdefaults[1595:72935] fetch NSDictionary - {
key1 = value1;
key2 = value2;
key3 = value3;
}
图片输出:
3、遵守NSCoding协议,使其支持自定义数据类型
person测试类:
#import <Foundation/Foundation.h>
@interface Person : NSObject <NSCoding>
@property(nonatomic, copy) NSString * name;
@property(nonatomic, assign) NSInteger age;
@end
#import "Person.h"
@implementation Person
- (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeInteger:self.age forKey:@"age"];
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeIntegerForKey:@"age"];
}
return self;
}
@end
测试数据:
Person * person = [[Person alloc] init];
person.name = @"dzl";
person.age = 25;
NSData * dataPerson = [NSKeyedArchiver archivedDataWithRootObject:person];
NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:dataPerson forKey:@"dataPerson"];
[userDefaults synchronize];
//取数据
NSData * fetchDataPerson = [userDefaults objectForKey:@"dataPerson"];
Person * fetchPerson = [NSKeyedUnarchiver unarchiveObjectWithData:fetchDataPerson];
NSLog(@"person.name = %@, person.age = %li", fetchPerson.name, (long)fetchPerson.age);
输出:
2015-11-11 12:31:09.589 01-nsuserdefaults[1756:80720] person.name = dzl, person.age = 25
其实NSString NSDictionary NSData NSDate 等都遵守NSSecureCoding协议,此协议又遵守NSCoding协议