// TestCodingProtocol.h // block练习 #import <Foundation/Foundation.h> @interface TestCodingProtocol : NSObject<NSCoding> #pragma mark- 持久化属性 @property(nonatomic,copy,readwrite) NSString* myName; @property(nonatomic,assign,readwrite)NSInteger myIndex; #pragma mark- 实现协议方法 - (void)encodeWithCoder:(NSCoder *)aCoder; - (id)initWithCoder:(NSCoder *)aDecoder; @end @interface TestCodingProtocolChild : TestCodingProtocol @property(nonatomic,assign,readwrite) NSInteger myIndexChild; -(void)encodeWithCoder:(NSCoder *)aCoder; -(id)initWithCoder:(NSCoder *)aDecoder; @end
// TestCodingProtocol.m // block练习 #import "TestCodingProtocol.h" @implementation TestCodingProtocol -(void)encodeWithCoder:(NSCoder *)aCoder { if (aCoder) { [aCoder encodeObject:self.myName forKey:@"myName"]; //self.myIndex为基础类型,不能用encodeObject [aCoder encodeInteger:self.myIndex forKey:@"myIndex"]; } } -(id)initWithCoder:(NSCoder *)aDecoder { if (self = [super init]) { if (!aDecoder) { return self; } self.myName = [aDecoder decodeObjectForKey:@"myName"]; self.myIndex = [aDecoder decodeIntegerForKey:@"myIndex"]; } return self; } @end @implementation TestCodingProtocolChild -(void)encodeWithCoder:(NSCoder *)aCoder { [super encodeWithCoder:aCoder]; [aCoder encodeInteger:self.myIndexChild forKey:@"myIndexChild"]; } -(id)initWithCoder:(NSCoder *)aDecoder { if (self = [super initWithCoder:aDecoder]) {//这里如果用init的话,父类的内容得不到初始化。 if (!aDecoder) { return self; } self.myIndexChild = [aDecoder decodeIntegerForKey:@"myIndexChild"]; } return self; } @end
TestCodingProtocol* t = [[TestCodingProtocol alloc] init]; t.myIndex = 5; t.myName = @"hello"; TestCodingProtocolChild* tChild = [[TestCodingProtocolChild alloc] init]; tChild.myIndex = 6; tChild.myName = @"child"; tChild.myIndexChild = 7; //增加几个基础类型。 NSString* s = @"helloworld"; NSNumber* n = [NSNumber numberWithInteger:5]; NSDate* d = [NSDate date]; NSData* dt = [NSKeyedArchiver archivedDataWithRootObject:t]; NSData* dChild = [NSKeyedArchiver archivedDataWithRootObject:tChild]; NSArray* r = [NSArray arrayWithObjects:s,n,d, nil];
NSUserDefaults* ud = [NSUserDefaults standardUserDefaults]; [ud setObject:r forKey:@"myData"]; //这里如果r里面带自己的类型实例的话,也不行,要转换成NSData [ud setObject:dt forKey:@"dt"]; //如果这个dt放入r里面,解析的时候就找不到特殊的标志了。 [ud setObject:dChild forKey:@"dChild"];//这三句话在第二次进入前屏蔽掉,也能读到,说明已经存储了。 id er = [ud objectForKey:@"myData"]; id et = [ud objectForKey:@"dt"]; id etChild = [ud objectForKey:@"dChild"]; if (et && [et isKindOfClass:[NSData class]]) { TestCodingProtocol* buf = [NSKeyedUnarchiver unarchiveObjectWithData:et]; NSLog(@"myIndex is %ld, myName is %@", buf.myIndex, buf.myName); } if (etChild && [etChild isKindOfClass:[NSData class]]) { TestCodingProtocolChild* buf = [NSKeyedUnarchiver unarchiveObjectWithData:etChild]; NSLog(@"myIndex is %ld, myName is %@, myIndexChild is %ld", buf.myIndex, buf.myName, buf.myIndexChild); } if ([er isKindOfClass:[NSArray class]]) { NSEnumerator* e = [er objectEnumerator]; id obj; while (obj = [e nextObject]) { if ([obj isKindOfClass:[TestCodingProtocolChild class]]) { NSLog(@"%@ 123",obj); } NSLog(@"%@",obj); } }总结下吧:
1,这个nsuserdefaults支持nsstring,nsdata,nsnumber,nsarray,nsdictionary。
2,自己定义的类还的借助于nskeyedarchiver和nskeyedunarchiver进行与nsdata的转换,如果直接用nskeyedarchiver也可以,见coding协议练习。
3,保存文件的位置目前还没有找到~~
参考http://blog.csdn.net/chyroger/article/details/5785297