之前已经实现了:
给Your Second iOS App:BirdWatching添加支持用户自定义图片
现在继续参考:
Your Second iOS App – Next Steps – Add More Functionality
的建议:
Make the master list persistent so that the user’s bird sightings are displayed every time they restart the app.
去添加,当用户退出程序,数据仍然保留,这样下次用于重新启动程序,仍然可以显示之前的数据。
1.去网上搜相关的内容,找到这里:
解释的:
用户束,NSUserDefault,或者写xml文件,写plist文件,数据库,CoreData都可以。
写沙盒,数据库等等方式多呢⋯⋯
和看到:[iOS]iOS中永久保存用户数据的两个地方 中也提到了NSUserDefault
2.所以就去学习NSUserDefault,可以参考:
但是那个教程很烂,代码都是乱凑出来的。
尤其是其中的firstName,后来还是在:
iOS SDK: 使用NSUserDefaults ( 后来找到了老外的原帖:iOS SDK: Working with NSUserDefaults)
找到的。
3.简单看了NSUserDefault,觉得还是有点不会用。
因为现在的情况是,当前的是一个数组,每个变量都是:
BirdSighting类型,其包括几个变量:
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *location;
@property (nonatomic, strong) NSDate *date;
@property (nonatomic) UIImage *image;
即包括四个变量,两个NSString,一个NSDate,一个UIImage
如果直接把数组中的每个BirdSighting的每个变量都是一点点保存,效率太低,逻辑也很混乱。
所以还是要想办法找到个方便,可以一起行保存整个数组的,包括每个BirdSighting中所包含的数据(字符的值,data的值,图片的数据)。
4.所以就又去找,找到一些参考资料:
Save NSArray to NSUserDefaults issues (using custom object in array)
所以继续去学习NSKeyedArchiver,
然后找到官网资料:
NSKeyedArchiver Class Reference
和
Archives and Serializations Programming Guide
然后也才知道,我所一直想要找的,Mac中的,类似于微软的C#中的序列化和反序列化,就是这个Archives。
5。看了半天教程,也还是很晕。
所以干脆参考:
How to store custom objects in NSUserDefaults
去实现代码。
最后显示试了如下代码:
-(void)initializeDefaultDataList{ NSMutableArray *sightingList = [[NSMutableArray alloc] init]; self.masterBirdSightingList = sightingList; //[self addBirdSightingWithName:@"Pigeon" location:@"Everywhere" date:[NSDate date] image:[UIImage imageNamed:@"defaultBirdImage.gif"] ]; //restore data NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSData *savedEncodedData = [defaults objectForKey:@"BirdSightingList"]; self.masterBirdSightingList = (NSMutableArray *)[NSKeyedUnarchiver unarchiveObjectWithData:savedEncodedData]; } -(void)addBirdSightingWithName:(NSString *)inputBirdName location:(NSString *)inputLocation date:(NSDate *)date image:(UIImage *)image{ BirdSighting *sighting; //NSDate *today = [NSDate date]; //sighting = [[BirdSighting alloc]initWithName:inputBirdName location:inputLocation date:today]; sighting = [[BirdSighting alloc]initWithName:inputBirdName location:inputLocation date:date image:image]; [self.masterBirdSightingList addObject:sighting]; //save data NSData *encodedCurBirdSightingList = [NSKeyedArchiver archivedDataWithRootObject:self.masterBirdSightingList]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:encodedCurBirdSightingList forKey:@"BirdSightingList"]; }
虽然调试过程中,可以看到encodedCurBirdSightingList是135个字节,但是最后的结果却是什么都没有显示。
很明显,只是保持了指针,但是没有保留数据,所以肯定是不显示内容的。
6.后来参考了原先官网文档的中文版:
中的解释:
如果您期望子类实例能够进行编解码,则子类应遵循
NSCoding
协议并实现initWithCoder:
以及encodeWithCoder:
方法,这些方法会在程序归解档某个对象图的时候被调用。
后,才明白,原来遵循NSCoding,就是实现了encodeWithCoder
和initWithCoder
,这样别人再去调用archivedDataWithRootObject
和unarchiveObjectWithData
,就会调用前面那两个函数了。
如果实现了将自定义的Object,实现了编码解码了。
7.关于如何实现自定义对象的NSMutableArray数组,保存和恢复自NSUserDefaults的逻辑和示例代码,可参考:
【已解决】iPhone/iOS中保存自定义对象(Custom Object/Custom Class)的数组(NSMutableArray/NSArray)到NSUserDefaults
【总结】
想要实现程序退出仍可以保留用户数据的话,可以通过将数据保存自/恢复自NSUserDefaults。
具体实现逻辑和参考代码,可参考:
【已解决】iPhone/iOS中保存自定义对象(Custom Object/Custom Class)的数组(NSMutableArray/NSArray)到NSUserDefaults
转载请注明:在路上 » 给Your Second iOS App:BirdWatching添加支持程序退出后,用户数据仍然保留